{
  "components": {
    "schemas": {
      "BuildDto": {
        "properties": {
          "channel": {
            "enum": [
              "dev",
              "qa",
              "alpha",
              "beta",
              "staging",
              "prod"
            ],
            "example": "production",
            "type": "string"
          },
          "gitCommit": {
            "example": "a1b2c3d4",
            "type": "string"
          },
          "platform": {
            "example": "windows",
            "type": "string"
          },
          "version": {
            "example": "1.14.2",
            "type": "string"
          }
        },
        "required": [
          "version",
          "platform"
        ],
        "type": "object"
      },
      "CreateEventDto": {
        "properties": {
          "buildId": {
            "format": "uuid",
            "type": "string"
          },
          "eventType": {
            "example": "player_action",
            "type": "string"
          },
          "occurredAt": {
            "format": "date-time",
            "type": "string"
          },
          "payload": {
            "type": "object"
          },
          "sessionId": {
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "sessionId",
          "eventType"
        ],
        "type": "object"
      },
      "CreateUploadDto": {
        "properties": {
          "attachmentType": {
            "enum": [
              "screenshot",
              "video",
              "save_state",
              "log_bundle",
              "other"
            ],
            "example": "log",
            "type": "string"
          },
          "fileName": {
            "example": "player-session.log",
            "type": "string"
          },
          "mimeType": {
            "example": "text/plain",
            "type": "string"
          },
          "sessionId": {
            "example": "3c2c5968-7a53-4cad-beb7-f157d6de60d3",
            "format": "uuid",
            "type": "string"
          },
          "sizeBytes": {
            "example": 24576,
            "minimum": 0,
            "type": "number"
          }
        },
        "required": [
          "sessionId",
          "attachmentType",
          "fileName"
        ],
        "type": "object"
      },
      "CreateUploadResponseDto": {
        "properties": {
          "expiresAt": {
            "format": "date-time",
            "type": "string"
          },
          "publicUrl": {
            "nullable": true,
            "type": "object"
          },
          "requiredHeaders": {
            "type": "object"
          },
          "storageKey": {
            "type": "string"
          },
          "uploadId": {
            "format": "uuid",
            "type": "string"
          },
          "uploadUrl": {
            "type": "string"
          }
        },
        "required": [
          "uploadId",
          "storageKey",
          "uploadUrl",
          "expiresAt",
          "requiredHeaders"
        ],
        "type": "object"
      },
      "EventResponseDto": {
        "properties": {
          "buildId": {
            "format": "uuid",
            "nullable": true,
            "type": "object"
          },
          "eventType": {
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "occurredAt": {
            "format": "date-time",
            "type": "string"
          },
          "overQuota": {
            "description": "True when this event fell over the tenant's monthly soft quota. Over-quota events are stored but excluded from paid features and downgraded in the UI.",
            "type": "boolean"
          },
          "payload": {
            "type": "object"
          },
          "reportIds": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "sessionId": {
            "format": "uuid",
            "nullable": true,
            "type": "object"
          }
        },
        "required": [
          "id",
          "eventType",
          "occurredAt",
          "payload",
          "reportIds",
          "overQuota"
        ],
        "type": "object"
      },
      "IssueExportStatusDto": {
        "properties": {
          "provider": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "status",
          "provider"
        ],
        "type": "object"
      },
      "PlayerDto": {
        "properties": {
          "deviceId": {
            "example": "device-7f2e4a8c",
            "type": "string"
          },
          "externalId": {
            "example": "steam_76561198000000000",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ReportAttachmentDto": {
        "properties": {
          "attachmentType": {
            "enum": [
              "screenshot",
              "video",
              "save_state",
              "log_bundle",
              "other"
            ],
            "example": "screenshot",
            "type": "string"
          },
          "fileName": {
            "example": "bug-1234.png",
            "type": "string"
          },
          "mimeType": {
            "example": "image/png",
            "type": "string"
          },
          "sizeBytes": {
            "example": 438122,
            "minimum": 0,
            "type": "number"
          },
          "uploadId": {
            "example": "4b9b34d0-59e3-4f67-8e6d-2c7f4afc2f80",
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "uploadId",
          "attachmentType",
          "fileName"
        ],
        "type": "object"
      },
      "ReportContextDto": {
        "properties": {
          "buildVersion": {
            "example": "1.14.2",
            "type": "string"
          },
          "checkpoint": {
            "example": "boss_room_before_cutscene",
            "type": "string"
          },
          "extra": {
            "example": {
              "currentQuest": "q_12_shadow_gate",
              "partySize": 3
            },
            "type": "object"
          },
          "locale": {
            "example": "cs-CZ",
            "type": "string"
          },
          "performance": {
            "example": {
              "fps": 47,
              "frameTimeMs": 21.3,
              "memoryMb": 2834
            },
            "type": "object"
          },
          "platform": {
            "example": "windows",
            "type": "string"
          },
          "playerPosition": {
            "example": {
              "x": 142.2,
              "y": 31.8,
              "z": -17.4
            },
            "type": "object"
          },
          "sceneName": {
            "example": "Dungeon_Level_03",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ReportEventDto": {
        "properties": {
          "eventType": {
            "example": "input",
            "type": "string"
          },
          "occurredAt": {
            "example": "2026-03-10T05:45:12.000Z",
            "format": "date-time",
            "type": "string"
          },
          "payload": {
            "example": {
              "action": "open_inventory",
              "key": "I"
            },
            "type": "object"
          }
        },
        "required": [
          "eventType"
        ],
        "type": "object"
      },
      "ReportExportDto": {
        "properties": {
          "enabled": {
            "example": true,
            "type": "boolean"
          },
          "provider": {
            "enum": [
              "github",
              "gitlab",
              "jira",
              "discord",
              "webhook"
            ],
            "example": "jira",
            "type": "string"
          }
        },
        "required": [
          "provider",
          "enabled"
        ],
        "type": "object"
      },
      "ReportPayloadDto": {
        "properties": {
          "description": {
            "example": "Crash happened after pressing I during combat.",
            "type": "string"
          },
          "fingerprint": {
            "description": "Client-provided deduplication hint mixed into dedupe key.",
            "example": "inventory-crash",
            "type": "string"
          },
          "reporterType": {
            "enum": [
              "player",
              "tester",
              "qa",
              "internal",
              "system"
            ],
            "example": "player",
            "type": "string"
          },
          "severity": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "example": "high",
            "type": "string"
          },
          "sourceChannel": {
            "example": "in-game-feedback",
            "type": "string"
          },
          "title": {
            "example": "Game crashed after opening inventory",
            "type": "string"
          }
        },
        "required": [
          "title"
        ],
        "type": "object"
      },
      "StartSessionDto": {
        "properties": {
          "build": {
            "$ref": "#/components/schemas/BuildDto"
          },
          "metadata": {
            "example": {
              "gameMode": "co-op",
              "region": "eu-central"
            },
            "type": "object"
          },
          "player": {
            "$ref": "#/components/schemas/PlayerDto"
          }
        },
        "required": [
          "build"
        ],
        "type": "object"
      },
      "StartSessionResponseDto": {
        "properties": {
          "buildId": {
            "format": "uuid",
            "type": "string"
          },
          "sessionId": {
            "format": "uuid",
            "type": "string"
          },
          "startedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "sessionId",
          "buildId",
          "startedAt"
        ],
        "type": "object"
      },
      "SubmitReportDto": {
        "properties": {
          "attachments": {
            "items": {
              "$ref": "#/components/schemas/ReportAttachmentDto"
            },
            "type": "array"
          },
          "buildId": {
            "description": "Optional override. If omitted, backend resolves build from sessionId.",
            "example": "f4f07e03-f5fe-4eef-9c99-95e142fcaef0",
            "format": "uuid",
            "type": "string"
          },
          "clientRequestId": {
            "description": "Client-generated idempotency key. Re-submission with the same value returns the original report. Optional for backward compatibility — when omitted the server generates one (no cross-request idempotency).",
            "example": "f9a05508-91a5-4b65-a00d-1301d5e7f078",
            "format": "uuid",
            "type": "string"
          },
          "context": {
            "$ref": "#/components/schemas/ReportContextDto"
          },
          "eventIds": {
            "description": "IDs of existing events that should be linked to the created bug report.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "events": {
            "items": {
              "$ref": "#/components/schemas/ReportEventDto"
            },
            "type": "array"
          },
          "export": {
            "$ref": "#/components/schemas/ReportExportDto"
          },
          "report": {
            "$ref": "#/components/schemas/ReportPayloadDto"
          },
          "sessionId": {
            "example": "3c2c5968-7a53-4cad-beb7-f157d6de60d3",
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "sessionId",
          "report"
        ],
        "type": "object"
      },
      "SubmitReportResponseDto": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "duplicateOf": {
            "format": "uuid",
            "type": "string"
          },
          "idempotent": {
            "example": false,
            "type": "boolean"
          },
          "issueExport": {
            "$ref": "#/components/schemas/IssueExportStatusDto"
          },
          "quotaExceeded": {
            "example": false,
            "type": "boolean"
          },
          "reportId": {
            "format": "uuid",
            "type": "string"
          },
          "staleDuplicateOf": {
            "format": "uuid",
            "type": "string"
          },
          "status": {
            "example": "accepted",
            "type": "string"
          }
        },
        "required": [
          "reportId",
          "status",
          "createdAt",
          "idempotent",
          "quotaExceeded"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "logger-token": {
        "description": "Plugin API token in the format: Bearer flg_...",
        "in": "header",
        "name": "Authorization",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "contact": {},
    "description": "Plugin ingest API — accepts sessions, uploads, reports and events from Forge Logger plugins.",
    "title": "Forge Logger Ingest API",
    "version": "1.0.0"
  },
  "openapi": "3.0.0",
  "paths": {
    "/health": {
      "get": {
        "operationId": "HealthController_check",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "details": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "type": "object"
                    },
                    "error": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "example": {},
                      "nullable": true,
                      "type": "object"
                    },
                    "info": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "nullable": true,
                      "type": "object"
                    },
                    "status": {
                      "example": "ok",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The Health Check is successful"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "details": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "example": {
                        "database": {
                          "status": "up"
                        },
                        "redis": {
                          "message": "Could not connect",
                          "status": "down"
                        }
                      },
                      "type": "object"
                    },
                    "error": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "example": {
                        "redis": {
                          "message": "Could not connect",
                          "status": "down"
                        }
                      },
                      "nullable": true,
                      "type": "object"
                    },
                    "info": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "nullable": true,
                      "type": "object"
                    },
                    "status": {
                      "example": "error",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The Health Check is not successful"
          }
        },
        "tags": [
          "Health"
        ]
      }
    },
    "/v1/ingest/events": {
      "post": {
        "operationId": "IngestController_createEvents",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "$ref": "#/components/schemas/CreateEventDto"
                },
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/EventResponseDto"
                  },
                  "type": "array"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "logger-token": []
          }
        ],
        "summary": "Submit one or more game events",
        "tags": [
          "Ingest"
        ]
      }
    },
    "/v1/ingest/reports": {
      "post": {
        "operationId": "IngestController_submitReport",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitReportDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitReportResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "logger-token": []
          }
        ],
        "summary": "Submit a bug report",
        "tags": [
          "Ingest"
        ]
      }
    },
    "/v1/ingest/sessions": {
      "post": {
        "operationId": "IngestController_startSession",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartSessionDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartSessionResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "logger-token": []
          }
        ],
        "summary": "Start a new game session",
        "tags": [
          "Ingest"
        ]
      }
    },
    "/v1/ingest/uploads": {
      "post": {
        "operationId": "IngestController_createUpload",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateUploadResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "logger-token": []
          }
        ],
        "summary": "Create an upload target for an attachment",
        "tags": [
          "Ingest"
        ]
      }
    }
  },
  "servers": [],
  "tags": []
}
