{
  "openapi": "3.1.1",
  "info": {
    "title": "ErrorHub.Api | v1",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://errorhub.dev/"
    }
  ],
  "paths": {
    "/api/v1/events": {
      "post": {
        "tags": [
          "Ingestion"
        ],
        "summary": "Submit one error event",
        "description": "Authenticate with the project ingestion key in the X-ErrorHub-Key header (a Bearer token is also accepted). Events are sanitized, fingerprinted and grouped into an issue. Resolved issues are reopened automatically when they happen again. A 429 carries a code: rate_limited for too many requests in a short time, quota_exceeded, budget_exhausted or plan_ceiling_reached when the account has used what its plan and spending mode allow.",
        "operationId": "IngestEvent",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestEventRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestEventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "Payload Too Large",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/options": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "What this deployment offers to someone who is not signed in",
        "operationId": "GetAuthOptions",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthOptionsDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Sign in to the dashboard",
        "operationId": "Login",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Sign out of the dashboard",
        "operationId": "Logout",
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/api/v1/auth/signup": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Create an account on the Free plan and sign in as its owner",
        "operationId": "SignUp",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignupRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/forgot-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Ask for a password reset link",
        "operationId": "ForgotPassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ForgotPasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Accepted"
          }
        }
      }
    },
    "/api/v1/auth/reset-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Choose a new password with the token from a reset link, and sign in",
        "operationId": "ResetPassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/verify-email": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Confirm an email address with the token from a verification link",
        "operationId": "VerifyEmail",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/invitations/preview": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Show what an invitation link leads to",
        "operationId": "PreviewInvitation",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitationPreviewDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/invitations/accept": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Join the account an invitation was sent from, and sign in",
        "operationId": "AcceptInvitation",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptInvitationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get the signed-in dashboard user",
        "operationId": "GetCurrentUser",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Authentication"
        ],
        "summary": "Change the name of the signed-in user",
        "operationId": "UpdateProfile",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProfileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/verification": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Send the verification link again",
        "operationId": "SendVerification",
        "responses": {
          "202": {
            "description": "Accepted"
          }
        }
      }
    },
    "/api/v1/auth/password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Change the password and end every other session",
        "operationId": "ChangePassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get the account, its plan and what it used in the current period",
        "operationId": "GetAccount",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountDto"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Account"
        ],
        "summary": "Rename the account or change what it may spend on extra events",
        "operationId": "UpdateAccount",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAccountRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Close the account and delete its projects, issues, events and users",
        "operationId": "DeleteAccount",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteAccountRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/team": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "List the people in the account and the invitations that are open",
        "operationId": "GetTeam",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TeamDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/invitations": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Invite a person to the account",
        "operationId": "CreateInvitation",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvitationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateInvitationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/invitations/{invitationId}": {
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Withdraw an invitation that was not accepted yet",
        "operationId": "RevokeInvitation",
        "parameters": [
          {
            "name": "invitationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/members/{memberId}": {
      "patch": {
        "tags": [
          "Account"
        ],
        "summary": "Change the role of a person in the account",
        "operationId": "UpdateMember",
        "parameters": [
          {
            "name": "memberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMemberRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Remove a person from the account",
        "operationId": "RemoveMember",
        "parameters": [
          {
            "name": "memberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/billing/checkout": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Start buying the Indie plan. Returns the address of the checkout page.",
        "operationId": "StartCheckout",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingRedirectDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/billing/portal": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Open the page where cards, invoices and cancelling are managed",
        "operationId": "OpenBillingPortal",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingRedirectDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "List the projects of the signed-in user's account",
        "operationId": "ListProjects",
        "parameters": [
          {
            "name": "includeArchived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProjectDto"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create a project and generate its ingestion credentials",
        "description": "The response contains the credentials that were just generated. Server keys are returned exactly once; public browser keys can be retrieved later from the setup endpoint.",
        "operationId": "CreateProject",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProjectRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateProjectResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "operationId": "GetProject",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Projects"
        ],
        "summary": "Rename a project or change its description or repository",
        "operationId": "UpdateProject",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProjectRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Delete a project with its keys, issues and events",
        "description": "Cannot be undone. To stop a project from reporting and keep its history, archive it.",
        "operationId": "DeleteProject",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/archive": {
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Archive a project",
        "description": "Archived projects keep their history but reject new events.",
        "operationId": "ArchiveProject",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/unarchive": {
      "post": {
        "tags": [
          "Projects"
        ],
        "operationId": "UnarchiveProject",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/keys": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "List ingestion keys",
        "description": "Public browser keys include their value; server keys are shown as a prefix only.",
        "operationId": "ListProjectKeys",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProjectApiKeyDto"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create an additional ingestion key",
        "operationId": "CreateProjectKey",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProjectKeyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectApiKeyDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/keys/{keyId}/rotate": {
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Rotate an ingestion key",
        "description": "Issues a replacement and revokes the previous key in one transaction.",
        "operationId": "RotateProjectKey",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectApiKeyDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/keys/{keyId}/revoke": {
      "post": {
        "tags": [
          "Projects"
        ],
        "operationId": "RevokeProjectKey",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/setup": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Integration instructions and the AI integration prompt for a project",
        "operationId": "GetProjectSetup",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectSetupDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "List issues with server-side filtering, sorting and paging",
        "description": "Filters: projectId, project (slug), status, source, level, environment, release, q, from, to. Sorting: sort=lastSeen|firstSeen|occurrences with order=asc|desc. Paging: page, pageSize.",
        "operationId": "ListIssues",
        "parameters": [
          {
            "name": "ProjectId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Project",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Archived",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Level",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Environment",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Release",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sort",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Order",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "IncludeArchivedProjects",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PagedResultOfIssueListItemDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/facets": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "Distinct environments, releases, levels, sources and statuses for the filter bar",
        "operationId": "GetIssueFacets",
        "parameters": [
          {
            "name": "Archived",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ProjectId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Project",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IncludeArchivedProjects",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueFacetsDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "One issue with its most recent occurrence",
        "operationId": "GetIssue",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Issues"
        ],
        "summary": "Delete an issue and every occurrence of it",
        "description": "Cannot be undone. If the error happens again it comes back as a new issue.",
        "operationId": "DeleteIssue",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}/prompt": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "A ready-to-paste prompt for a coding agent to investigate and fix the issue",
        "operationId": "GetIssueFixPrompt",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixPromptDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}/events": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "Occurrences of an issue, newest first",
        "operationId": "ListIssueEvents",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PagedResultOfIssueEventSummaryDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/events/{eventId}": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "One occurrence in full, including its stack trace and sanitized context",
        "operationId": "GetEvent",
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueEventDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}/resolve": {
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Mark an issue as resolved",
        "description": "A later occurrence of the same error reopens the issue automatically.",
        "operationId": "ResolveIssue",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}/reopen": {
      "post": {
        "tags": [
          "Issues"
        ],
        "operationId": "ReopenIssue",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}/archive": {
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Hide an issue",
        "description": "Archived issues are hidden from the default list and never alert; occurrences keep counting.",
        "operationId": "ArchiveIssue",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/{issueId}/unarchive": {
      "post": {
        "tags": [
          "Issues"
        ],
        "operationId": "UnarchiveIssue",
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueDetailDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/issues/bulk": {
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Resolve, reopen, archive or unarchive many issues at once",
        "description": "Send issueIds to act on a selection. Omit them to act on every issue matching the list filters in the query string (same parameters as GET /issues, all pages).",
        "operationId": "BulkUpdateIssues",
        "parameters": [
          {
            "name": "ProjectId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Project",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Archived",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Level",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Environment",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Release",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sort",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Order",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "IncludeArchivedProjects",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IssueBulkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueBulkResultDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/push/config": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "Whether push is available and the VAPID public key browsers subscribe with",
        "operationId": "GetPushConfig",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushConfigDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/push/devices": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "Devices receiving alerts for the signed-in user; pass endpoint to flag this browser",
        "operationId": "ListPushDevices",
        "parameters": [
          {
            "name": "endpoint",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PushDeviceDto"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/push/subscriptions": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Register this browser for alerts",
        "operationId": "SubscribePush",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PushSubscribeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/push/subscriptions/remove": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Stop alerts for this browser",
        "operationId": "UnsubscribePush",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PushUnsubscribeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/push/devices/{deviceId}": {
      "delete": {
        "tags": [
          "Notifications"
        ],
        "summary": "Stop alerts for one of the signed-in user's devices",
        "operationId": "RemovePushDevice",
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/push/test": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Send a test notification to every device of the signed-in user",
        "operationId": "SendTestPush",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushTestResultDto"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AcceptInvitationRequest": {
        "required": [
          "token",
          "password"
        ],
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "displayName": {
            "type": [
              "null",
              "string"
            ]
          },
          "acceptTerms": {
            "type": "boolean",
            "default": false
          }
        },
        "description": "Joins the account an invitation was sent from, creating the invited user."
      },
      "AccountDto": {
        "required": [
          "id",
          "name",
          "plan",
          "spendingMode",
          "extraBudgetCents",
          "usage",
          "billing",
          "userCount",
          "createdAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "plan": {
            "$ref": "#/components/schemas/PlanDto"
          },
          "spendingMode": {
            "$ref": "#/components/schemas/SpendingMode"
          },
          "extraBudgetCents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "usage": {
            "$ref": "#/components/schemas/UsageDto"
          },
          "billing": {
            "$ref": "#/components/schemas/BillingDto"
          },
          "userCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AccountPlan": {
        "enum": [
          "free",
          "indie",
          "scale"
        ]
      },
      "ApiKeyKind": {
        "enum": [
          "server",
          "public"
        ]
      },
      "AuthOptionsDto": {
        "required": [
          "signupEnabled",
          "emailEnabled"
        ],
        "type": "object",
        "properties": {
          "signupEnabled": {
            "type": "boolean",
            "description": "New accounts can be created."
          },
          "emailEnabled": {
            "type": "boolean",
            "description": "The server can send mail, so password reset links exist."
          }
        },
        "description": "What this deployment offers to someone who is not signed in yet."
      },
      "BillingDto": {
        "required": [
          "available",
          "sellsExtraEvents",
          "status",
          "hasCustomer",
          "cancelAtPeriodEnd",
          "currentPeriodEnd"
        ],
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean"
          },
          "sellsExtraEvents": {
            "type": "boolean"
          },
          "status": {
            "$ref": "#/components/schemas/SubscriptionStatus"
          },
          "hasCustomer": {
            "type": "boolean"
          },
          "cancelAtPeriodEnd": {
            "type": "boolean"
          },
          "currentPeriodEnd": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        },
        "description": "State of the paid subscription. Available says that this deployment has a billing provider\nconfigured, SellsExtraEvents that pay-as-you-go can be invoiced (so the spending mode can be\nchanged), and HasCustomer that the account exists at the provider, so invoices can be managed there."
      },
      "BillingRedirectDto": {
        "required": [
          "url"
        ],
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          }
        },
        "description": "Where to send the browser: a checkout page or the billing portal of the provider."
      },
      "ChangePasswordRequest": {
        "required": [
          "currentPassword",
          "newPassword"
        ],
        "type": "object",
        "properties": {
          "currentPassword": {
            "type": "string"
          },
          "newPassword": {
            "type": "string"
          }
        }
      },
      "CreateInvitationRequest": {
        "required": [
          "email"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          }
        }
      },
      "CreateInvitationResponse": {
        "required": [
          "invitation",
          "emailSent",
          "link"
        ],
        "type": "object",
        "properties": {
          "invitation": {
            "$ref": "#/components/schemas/InvitationDto"
          },
          "emailSent": {
            "type": "boolean"
          },
          "link": {
            "type": "string"
          }
        },
        "description": "The invitation that was just created. The link is only returned here, for the case where the\nserver cannot send mail and the person who invited has to pass it on."
      },
      "CreateProjectKeyRequest": {
        "required": [
          "kind"
        ],
        "type": "object",
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/ApiKeyKind"
          },
          "name": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "Request to mint an extra ingestion credential for an existing project."
      },
      "CreateProjectRequest": {
        "required": [
          "name"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": [
              "null",
              "string"
            ]
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "platform": {
            "$ref": "#/components/schemas/ProjectPlatform"
          },
          "repository": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "Creation request from the setup wizard. Platform decides which ingestion\ncredentials are generated: a server key, a public browser key, or both."
      },
      "CreateProjectResponse": {
        "required": [
          "project",
          "setup"
        ],
        "type": "object",
        "properties": {
          "project": {
            "$ref": "#/components/schemas/ProjectDto"
          },
          "setup": {
            "$ref": "#/components/schemas/ProjectSetupDto"
          }
        },
        "description": "Result of the setup wizard: the project, its new credentials (once) and the instructions."
      },
      "CurrentUserDto": {
        "required": [
          "id",
          "email",
          "displayName",
          "role",
          "accountId",
          "accountName",
          "plan",
          "emailVerified"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountName": {
            "type": "string"
          },
          "plan": {
            "$ref": "#/components/schemas/AccountPlan"
          },
          "emailVerified": {
            "type": "boolean"
          }
        },
        "description": "The signed-in user, and the account everything they see belongs to."
      },
      "DeleteAccountRequest": {
        "required": [
          "password"
        ],
        "type": "object",
        "properties": {
          "password": {
            "type": "string"
          }
        },
        "description": "Closes the account and deletes everything in it. The password is asked for again, because a\nsession that was left open on a shared machine must not be enough for this."
      },
      "ErrorLevel": {
        "enum": [
          "debug",
          "info",
          "warning",
          "error",
          "fatal",
          null
        ]
      },
      "ErrorSource": {
        "enum": [
          "backend",
          "frontend",
          null
        ]
      },
      "FacetValueDto": {
        "required": [
          "value",
          "count"
        ],
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "count": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        },
        "description": "One distinct filter value and how many issues currently carry it."
      },
      "FixPromptDto": {
        "required": [
          "prompt"
        ],
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string"
          }
        },
        "description": "Markdown prompt that hands one issue to a coding agent."
      },
      "ForgotPasswordRequest": {
        "required": [
          "email"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          }
        },
        "description": "Asks for a password reset link. The reply never says whether the address has an account."
      },
      "HttpValidationProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "IngestEventRequest": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": [
              "null",
              "string"
            ],
            "description": "Client-side time of the exception. Sandboxed server-side, so a wrong clock cannot poison the data.",
            "format": "date-time"
          },
          "source": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "description": "Backend or Frontend. Defaults to the kind of ingestion key used.",
                "$ref": "#/components/schemas/ErrorSource"
              }
            ]
          },
          "level": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ErrorLevel"
              }
            ]
          },
          "environment": {
            "type": [
              "null",
              "string"
            ],
            "description": "For example \"Production\". Free text, truncated to a sane length."
          },
          "release": {
            "type": [
              "null",
              "string"
            ],
            "description": "Application version/commit deployed when the error happened."
          },
          "message": {
            "type": [
              "null",
              "string"
            ],
            "description": "Human readable one-line summary."
          },
          "exceptionType": {
            "type": [
              "null",
              "string"
            ]
          },
          "exceptionMessage": {
            "type": [
              "null",
              "string"
            ]
          },
          "stackTrace": {
            "type": [
              "null",
              "string"
            ],
            "description": "Raw stack trace. Text, deliberately never rendered as HTML."
          },
          "request": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/IngestRequestInfo"
              }
            ]
          },
          "user": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/IngestUserInfo"
              }
            ]
          },
          "tags": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "Searchable key/value pairs (region, tenant, feature flag, ...)."
          },
          "context": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "description": "Arbitrary structured diagnostics. Recursively sanitized and bounded by the server.",
                "$ref": "#/components/schemas/JsonNode"
              }
            ]
          },
          "sdk": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/IngestSdkInfo"
              }
            ]
          }
        },
        "description": "The event envelope every SDK posts to `POST /api/v1/events`.\n\nEverything except the error itself is optional: the SDK should be able to report a bare exception\nwithout ceremony. Nulls are omitted on the wire (see ErrorHubJson)."
      },
      "IngestEventResponse": {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "default": "accepted"
          }
        },
        "description": "Minimal acknowledgement. Intentionally carries no project data: an ingestion key must not be a\nway to learn anything about the account."
      },
      "IngestRequestInfo": {
        "type": "object",
        "properties": {
          "method": {
            "type": [
              "null",
              "string"
            ]
          },
          "path": {
            "type": [
              "null",
              "string"
            ],
            "description": "Path only. The server strips the query string because it routinely carries tokens."
          },
          "requestId": {
            "type": [
              "null",
              "string"
            ],
            "description": "ASP.NET Core `HttpContext.TraceIdentifier` or an equivalent correlation id."
          }
        },
        "description": "HTTP request facts. The body and all headers are deliberately absent from this contract."
      },
      "IngestSdkInfo": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "version": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "IngestUserInfo": {
        "type": "object",
        "properties": {
          "identifier": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "Opaque, application-defined user identifier. Never an email, password or token."
      },
      "InvitationDto": {
        "required": [
          "id",
          "email",
          "role",
          "createdAt",
          "expiresAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "InvitationPreviewDto": {
        "required": [
          "email",
          "accountName",
          "role"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          }
        },
        "description": "What an invitation link leads to, shown before the invited person chooses a password."
      },
      "IssueBulkAction": {
        "enum": [
          "resolve",
          "reopen",
          "archive",
          "unarchive"
        ],
        "description": "What a bulk operation does to each issue."
      },
      "IssueBulkRequest": {
        "required": [
          "action"
        ],
        "type": "object",
        "properties": {
          "action": {
            "$ref": "#/components/schemas/IssueBulkAction"
          },
          "issueIds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "description": "A bulk change. With IReadOnlyList&lt;Guid&gt;? IssueBulkRequest.IssueIds it applies to those issues; without, to every issue that\nmatches the list filters sent in the query string (all pages, not just the visible one)."
      },
      "IssueBulkResultDto": {
        "required": [
          "matched",
          "changed"
        ],
        "type": "object",
        "properties": {
          "matched": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "changed": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        },
        "description": "How many issues matched and how many actually changed."
      },
      "IssueDetailDto": {
        "required": [
          "id",
          "projectId",
          "projectSlug",
          "projectName",
          "fingerprint",
          "title",
          "exceptionType",
          "source",
          "level",
          "status",
          "firstSeenAt",
          "lastSeenAt",
          "occurrenceCount",
          "lastEnvironment",
          "lastRelease",
          "lastEventId",
          "resolvedAt",
          "resolvedByUserId",
          "latestEvent"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "projectSlug": {
            "type": "string"
          },
          "projectName": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "exceptionType": {
            "type": [
              "null",
              "string"
            ]
          },
          "source": {
            "$ref": "#/components/schemas/ErrorSource"
          },
          "level": {
            "$ref": "#/components/schemas/ErrorLevel"
          },
          "status": {
            "$ref": "#/components/schemas/IssueStatus"
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "occurrenceCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "lastEnvironment": {
            "type": [
              "null",
              "string"
            ]
          },
          "lastRelease": {
            "type": [
              "null",
              "string"
            ]
          },
          "lastEventId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "resolvedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "resolvedByUserId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "latestEvent": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/IssueEventDetailDto"
              }
            ]
          },
          "archivedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        },
        "description": "Issue header plus the most recent occurrence, which is what a developer looks at first."
      },
      "IssueEventDetailDto": {
        "required": [
          "id",
          "projectId",
          "issueId",
          "timestamp",
          "receivedAt",
          "source",
          "level",
          "environment",
          "release",
          "message",
          "exceptionType",
          "exceptionMessage",
          "stackTrace",
          "requestMethod",
          "requestPath",
          "requestId",
          "userIdentifier",
          "tags",
          "context",
          "sdkName",
          "sdkVersion"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "issueId": {
            "type": "string",
            "format": "uuid"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "$ref": "#/components/schemas/ErrorSource"
          },
          "level": {
            "$ref": "#/components/schemas/ErrorLevel"
          },
          "environment": {
            "type": [
              "null",
              "string"
            ]
          },
          "release": {
            "type": [
              "null",
              "string"
            ]
          },
          "message": {
            "type": [
              "null",
              "string"
            ]
          },
          "exceptionType": {
            "type": [
              "null",
              "string"
            ]
          },
          "exceptionMessage": {
            "type": [
              "null",
              "string"
            ]
          },
          "stackTrace": {
            "type": [
              "null",
              "string"
            ]
          },
          "requestMethod": {
            "type": [
              "null",
              "string"
            ]
          },
          "requestPath": {
            "type": [
              "null",
              "string"
            ]
          },
          "requestId": {
            "type": [
              "null",
              "string"
            ]
          },
          "userIdentifier": {
            "type": [
              "null",
              "string"
            ]
          },
          "tags": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/JsonElement"
              }
            ]
          },
          "context": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/JsonElement"
              }
            ]
          },
          "sdkName": {
            "type": [
              "null",
              "string"
            ]
          },
          "sdkVersion": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "Full detail of one occurrence, including the stack trace and sanitized diagnostics."
      },
      "IssueEventSummaryDto": {
        "required": [
          "id",
          "timestamp",
          "receivedAt",
          "source",
          "level",
          "environment",
          "release",
          "message",
          "exceptionType",
          "exceptionMessage",
          "requestMethod",
          "requestPath",
          "requestId",
          "userIdentifier",
          "sdkName",
          "sdkVersion"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "$ref": "#/components/schemas/ErrorSource"
          },
          "level": {
            "$ref": "#/components/schemas/ErrorLevel"
          },
          "environment": {
            "type": [
              "null",
              "string"
            ]
          },
          "release": {
            "type": [
              "null",
              "string"
            ]
          },
          "message": {
            "type": [
              "null",
              "string"
            ]
          },
          "exceptionType": {
            "type": [
              "null",
              "string"
            ]
          },
          "exceptionMessage": {
            "type": [
              "null",
              "string"
            ]
          },
          "requestMethod": {
            "type": [
              "null",
              "string"
            ]
          },
          "requestPath": {
            "type": [
              "null",
              "string"
            ]
          },
          "requestId": {
            "type": [
              "null",
              "string"
            ]
          },
          "userIdentifier": {
            "type": [
              "null",
              "string"
            ]
          },
          "sdkName": {
            "type": [
              "null",
              "string"
            ]
          },
          "sdkVersion": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "Compact event row for the \"recent occurrences\" list on the issue details screen."
      },
      "IssueFacetsDto": {
        "required": [
          "environments",
          "releases",
          "levels",
          "sources",
          "statuses"
        ],
        "type": "object",
        "properties": {
          "environments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FacetValueDto"
            }
          },
          "releases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FacetValueDto"
            }
          },
          "levels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FacetValueDto"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FacetValueDto"
            }
          },
          "statuses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FacetValueDto"
            }
          }
        },
        "description": "Filter options for the issues screen, computed with grouped queries so the dropdowns never require\nloading issues into memory."
      },
      "IssueListItemDto": {
        "required": [
          "id",
          "projectId",
          "projectSlug",
          "projectName",
          "fingerprint",
          "title",
          "exceptionType",
          "source",
          "level",
          "status",
          "firstSeenAt",
          "lastSeenAt",
          "occurrenceCount",
          "lastEnvironment",
          "lastRelease",
          "lastEventId",
          "resolvedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "projectSlug": {
            "type": "string"
          },
          "projectName": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "exceptionType": {
            "type": [
              "null",
              "string"
            ]
          },
          "source": {
            "$ref": "#/components/schemas/ErrorSource"
          },
          "level": {
            "$ref": "#/components/schemas/ErrorLevel"
          },
          "status": {
            "$ref": "#/components/schemas/IssueStatus"
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "occurrenceCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "lastEnvironment": {
            "type": [
              "null",
              "string"
            ]
          },
          "lastRelease": {
            "type": [
              "null",
              "string"
            ]
          },
          "lastEventId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "resolvedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "archivedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        },
        "description": "Row of the issues list. Contains no event payload so listing never loads event data."
      },
      "IssueStatus": {
        "enum": [
          "open",
          "resolved"
        ]
      },
      "JsonElement": { },
      "JsonNode": { },
      "LoginRequest": {
        "required": [
          "email",
          "password"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "password": {
            "type": "string"
          }
        },
        "description": "Dashboard sign-in. Separate from project ingestion credentials by design."
      },
      "MemberDto": {
        "required": [
          "id",
          "email",
          "displayName",
          "role",
          "createdAt",
          "lastLoginAt",
          "emailVerified",
          "isCurrentUser"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastLoginAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "emailVerified": {
            "type": "boolean"
          },
          "isCurrentUser": {
            "type": "boolean"
          }
        }
      },
      "PagedResultOfIssueEventSummaryDto": {
        "required": [
          "items",
          "page",
          "pageSize",
          "totalCount"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssueEventSummaryDto"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "totalCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "totalPages": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        },
        "description": "A page of results plus the total count, so the dashboard can paginate without loading everything."
      },
      "PagedResultOfIssueListItemDto": {
        "required": [
          "items",
          "page",
          "pageSize",
          "totalCount"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssueListItemDto"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "totalCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "totalPages": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        },
        "description": "A page of results plus the total count, so the dashboard can paginate without loading everything."
      },
      "PlanDto": {
        "required": [
          "plan",
          "name",
          "monthlyPriceCents",
          "includedEvents",
          "eventRetentionDays",
          "maxUsers",
          "extraCentsPerThousand",
          "eventCeiling"
        ],
        "type": "object",
        "properties": {
          "plan": {
            "$ref": "#/components/schemas/AccountPlan"
          },
          "name": {
            "type": "string"
          },
          "monthlyPriceCents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "includedEvents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "eventRetentionDays": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "maxUsers": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "extraCentsPerThousand": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "eventCeiling": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          }
        },
        "description": "What the plan of an account includes. Prices are in euro cents and exclude VAT."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ProjectApiKeyDto": {
        "required": [
          "id",
          "kind",
          "name",
          "prefix",
          "createdAt",
          "revokedAt",
          "lastUsedAt",
          "key"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "$ref": "#/components/schemas/ApiKeyKind"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "key": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "A credential as shown in the dashboard. Key is only populated when the\nplaintext value is intentionally retrievable: immediately after creation/rotation, or for public\nbrowser keys (which are public by design and must be readable to re-copy into a front-end build)."
      },
      "ProjectDto": {
        "required": [
          "id",
          "name",
          "slug",
          "description",
          "platform",
          "createdAt",
          "archivedAt",
          "openIssueCount",
          "totalIssueCount"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "platform": {
            "$ref": "#/components/schemas/ProjectPlatform"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "archivedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "openIssueCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "totalIssueCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "repository": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ProjectPlatform": {
        "enum": [
          "backend",
          "frontend",
          "both"
        ]
      },
      "ProjectSetupDto": {
        "required": [
          "projectId",
          "projectName",
          "slug",
          "ingestUrl",
          "serverKey",
          "publicKey",
          "installPrompt",
          "serverKeyPlaceholder"
        ],
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "description": "The project the keys belong to.",
            "format": "uuid"
          },
          "projectName": {
            "type": "string",
            "description": "Display name, as used in the prompt."
          },
          "slug": {
            "type": "string",
            "description": "URL-safe project identifier."
          },
          "ingestUrl": {
            "type": "string",
            "description": "Absolute URL events are POSTed to."
          },
          "serverKey": {
            "type": [
              "null",
              "string"
            ],
            "description": "The secret server key. Only present in the response that created or rotated it."
          },
          "publicKey": {
            "type": [
              "null",
              "string"
            ],
            "description": "The browser key. Public by design, so it stays retrievable."
          },
          "installPrompt": {
            "type": "string",
            "description": "Paste-ready instructions for a coding agent. When the server key is not available it contains\n`ServerKeyPlaceholder` instead."
          },
          "serverKeyPlaceholder": {
            "type": "string",
            "description": "The token standing in for the server key, so the dashboard can fill in a freshly rotated key."
          }
        },
        "description": "Everything needed to connect an application: the ingestion endpoint, the keys and a prompt that lets a\ncoding agent do the integration. There is no SDK; applications report with one HTTP POST."
      },
      "PushConfigDto": {
        "required": [
          "enabled",
          "publicKey"
        ],
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "publicKey": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "PushDeviceDto": {
        "required": [
          "id",
          "deviceLabel",
          "createdAt",
          "lastSuccessAt",
          "isCurrent"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "deviceLabel": {
            "type": [
              "null",
              "string"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSuccessAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "isCurrent": {
            "type": "boolean"
          }
        }
      },
      "PushKeys": {
        "required": [
          "p256dh",
          "auth"
        ],
        "type": "object",
        "properties": {
          "p256dh": {
            "type": [
              "null",
              "string"
            ]
          },
          "auth": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "PushSubscribeRequest": {
        "required": [
          "endpoint",
          "keys",
          "deviceLabel"
        ],
        "type": "object",
        "properties": {
          "endpoint": {
            "type": [
              "null",
              "string"
            ]
          },
          "keys": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/PushKeys"
              }
            ]
          },
          "deviceLabel": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "PushTestResultDto": {
        "required": [
          "delivered",
          "removed",
          "failed"
        ],
        "type": "object",
        "properties": {
          "delivered": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "removed": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "failed": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "PushUnsubscribeRequest": {
        "required": [
          "endpoint"
        ],
        "type": "object",
        "properties": {
          "endpoint": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ResetPasswordRequest": {
        "required": [
          "token",
          "password"
        ],
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          },
          "password": {
            "type": "string"
          }
        },
        "description": "Sets a new password with the token from a reset link."
      },
      "SignupRequest": {
        "required": [
          "email",
          "password"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "displayName": {
            "type": [
              "null",
              "string"
            ]
          },
          "accountName": {
            "type": [
              "null",
              "string"
            ]
          },
          "acceptTerms": {
            "type": "boolean",
            "default": false
          }
        },
        "description": "Creates an account and its first user, the owner. Only the email and the password are required:\nthe name of the account defaults to something derived from the email and can be changed later.\nAcceptTerms says that the person agreed to the terms of service and read the privacy policy."
      },
      "SpendingMode": {
        "enum": [
          "hardLimit",
          "budget",
          "unlimited"
        ]
      },
      "SubscriptionStatus": {
        "enum": [
          "none",
          "active",
          "pastDue",
          "canceled"
        ]
      },
      "TeamDto": {
        "required": [
          "members",
          "invitations",
          "maxUsers"
        ],
        "type": "object",
        "properties": {
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemberDto"
            }
          },
          "invitations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvitationDto"
            }
          },
          "maxUsers": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "UpdateAccountRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "spendingMode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SpendingMode"
              }
            ]
          },
          "extraBudgetCents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          }
        },
        "description": "Changes to an account. Omitted fields stay as they are."
      },
      "UpdateMemberRequest": {
        "required": [
          "role"
        ],
        "type": "object",
        "properties": {
          "role": {
            "$ref": "#/components/schemas/UserRole"
          }
        }
      },
      "UpdateProfileRequest": {
        "required": [
          "displayName"
        ],
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string"
          }
        },
        "description": "Changes how the signed-in user is called in the dashboard and in invitations."
      },
      "UpdateProjectRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "repository": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "Partial update. A null property means \"leave unchanged\"."
      },
      "UsageDto": {
        "required": [
          "periodStart",
          "periodEnd",
          "acceptedEvents",
          "includedEvents",
          "maximumEvents",
          "extraEvents",
          "extraCents",
          "rejectedEvents",
          "limitReached"
        ],
        "type": "object",
        "properties": {
          "periodStart": {
            "type": "string",
            "format": "date-time"
          },
          "periodEnd": {
            "type": "string",
            "format": "date-time"
          },
          "acceptedEvents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "includedEvents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "maximumEvents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "extraEvents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "extraCents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "rejectedEvents": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "limitReached": {
            "type": "boolean"
          }
        },
        "description": "Usage of the current period, including events accepted in the last few seconds. The maximum is\nthe most events the period can hold with the current spending mode and budget. Extra events are the\naccepted events beyond the included volume, and their cost excludes VAT. Rejected events were\nrefused because a limit was reached and are never billed."
      },
      "UserRole": {
        "enum": [
          "member",
          "admin",
          "owner"
        ]
      },
      "VerifyEmailRequest": {
        "required": [
          "token"
        ],
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          }
        },
        "description": "Confirms an email address with the token from a verification link."
      }
    }
  },
  "tags": [
    {
      "name": "Ingestion"
    },
    {
      "name": "Authentication"
    },
    {
      "name": "Account"
    },
    {
      "name": "Projects"
    },
    {
      "name": "Issues"
    },
    {
      "name": "Notifications"
    }
  ]
}