{
  "openapi": "3.0.3",
  "info": {
    "title": "Vault Developer API",
    "description": "API for developers that want to make custom extensions to Vault for their group.",
    "version": "2.0"
  },
  "paths": {
    "/api/developers/vault": {
      "get": {
        "summary": "Get Vault Information",
        "description": "Returns the authenticated user's vault information.",
        "tags": ["Vault"],
        "security": [{ "vaultDevAuth": [] }],
        "responses": {
          "200": {
            "description": "Successful response with Vault data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "name": { "type": "string" },
                        "uuid": { "type": "string" },
                        "description": { "type": "string", "nullable": true },
                        "groupID": { "type": "integer", "nullable": true },
                        "discordID": { "type": "string", "nullable": true },
                        "tags": {
                          "type": "array",
                          "items": { "type": "string" },
                          "nullable": true
                        },
                        "terms": { "type": "string", "nullable": true },
                        "refunds": { "type": "string", "nullable": true },
                        "createdTimestamp": {
                          "type": "integer",
                          "description": "Unix timestamp"
                        }
                      },
                      "required": ["name", "uuid"]
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["data", "error"]
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/profile": {
      "post": {
        "summary": "Get Profile by Roblox or Discord ID",
        "description": "Returns user data and product licenses by robloxID or discordID.",
        "tags": ["Profile"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "robloxID": { "type": "string", "example": "123456789" },
                  "discordID": {
                    "type": "string",
                    "example": "742194720128712774"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response with profile and product data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "robloxID": { "type": "string" },
                        "robloxUsername": { "type": "string", "nullable": true },
                        "thumbnail": {
                          "type": "string",
                          "format": "uri",
                          "nullable": true
                        },
                        "discordID": { "type": "string", "nullable": true },
                        "discordUsername": {
                          "type": "string",
                          "nullable": true
                        },
                        "products": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": { "type": "string" },
                              "description": { "type": "string" },
                              "productUUID": { "type": "string" },
                              "productID": { "type": "string" },
                              "robux": {
                                "type": "number",
                                "description": "Price in Robux from developer product, 0 if it has no productID or Roblox can't return the price"
                              },
                              "images": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "format": "uri",
                                  "example": "https://cdn.vaultroblox.com/<imageKey>"
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "error": { "type": "boolean", "example": false }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing or invalid robloxID/discordID",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/vault/products": {
      "get": {
        "summary": "Get Vault Products",
        "description": "Returns all products associated with the authenticated vault.",
        "tags": ["Vault"],
        "security": [{ "vaultDevAuth": [] }],
        "responses": {
          "200": {
            "description": "Successful response with list of products",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": { "type": "string" },
                          "category": { "type": "string" },
                          "description": { "type": "string" },
                          "tags": {
                            "type": "array",
                            "items": { "type": "string" }
                          },
                          "onsale": { "type": "boolean" },
                          "transfer": { "type": "boolean" },
                          "productID": { "type": "string" },
                          "productUUID": { "type": "string" },
                          "robux": {
                            "type": "number",
                            "description": "Price in Robux from developer product, 0 if it has no productID or Roblox can't return the price"
                          },
                          "images": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "format": "uri",
                              "example": "https://cdn.vaultroblox.com/<imageKey>"
                            }
                          }
                        }
                      }
                    },
                    "error": { "type": "boolean", "example": false }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/licenses/add": {
      "post": {
        "summary": "Add License to Account",
        "description": "Adds a license for a product to a Roblox or Discord account.",
        "tags": ["Licenses"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "description": "License information",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "robloxID": { "type": "string", "nullable": true },
                  "discordID": { "type": "string", "nullable": true },
                  "productUUID": {
                    "type": "string",
                    "nullable": true,
                    "description": "UUID of the product to add license for"
                  },
                  "productName": {
                    "type": "string",
                    "nullable": true,
                    "description": "Name of the product to add license for (alternative to productUUID)"
                  }
                },
                "anyOf": [
                  { "required": ["productUUID"] },
                  { "required": ["productName"] },
                  { "required": ["productID"] }
                ],
                "oneOf": [
                  { "required": ["robloxID"] },
                  { "required": ["discordID"] }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License added successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "License added successfully to the account"
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["message", "error"]
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing productUUID/productName, missing robloxID/discordID, product not found, or license already exists",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/licenses/check": {
      "post": {
        "summary": "Check License Status",
        "description": "Checks if a Roblox or Discord account owns a license for a specified product.",
        "tags": ["Licenses"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "description": "License check parameters",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "robloxID": { "type": "string", "nullable": true },
                  "discordID": { "type": "string", "nullable": true },
                  "productUUID": { "type": "string" }
                },
                "required": ["productUUID"],
                "oneOf": [
                  { "required": ["robloxID"] },
                  { "required": ["discordID"] }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License status response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "licensed": { "type": "boolean" },
                        "robloxID": { "type": "string", "nullable": true },
                        "robloxUsername": { "type": "string", "nullable": true },
                        "reason": { "type": "string", "nullable": true },
                        "issuedTimestamp": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "required": ["licensed"]
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["data", "error"]
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing fields or account not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/licenses/delete": {
      "delete": {
        "summary": "Delete License from Account",
        "description": "Deletes a license for a product from a Roblox or Discord account.",
        "tags": ["Licenses"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "description": "License deletion parameters",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "robloxID": { "type": "string", "nullable": true },
                  "discordID": { "type": "string", "nullable": true },
                  "productUUID": { "type": "string" }
                },
                "required": ["productUUID"],
                "oneOf": [
                  { "required": ["robloxID"] },
                  { "required": ["discordID"] }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "License deleted from the account"
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["message", "error"]
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing fields or license/account issues",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/licenses/transfer": {
      "post": {
        "summary": "Transfer License Between Accounts",
        "description": "Transfers a license for a product from one account to another (Roblox or Discord).",
        "tags": ["Licenses"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "description": "License transfer parameters",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fromRobloxID": {
                    "type": "string",
                    "nullable": true,
                    "description": "Source Roblox ID"
                  },
                  "fromDiscordID": {
                    "type": "string",
                    "nullable": true,
                    "description": "Source Discord ID"
                  },
                  "toRobloxID": {
                    "type": "string",
                    "nullable": true,
                    "description": "Destination Roblox ID"
                  },
                  "toDiscordID": {
                    "type": "string",
                    "nullable": true,
                    "description": "Destination Discord ID"
                  },
                  "productUUID": {
                    "type": "string",
                    "nullable": true,
                    "description": "UUID of the product to transfer"
                  },
                  "productName": {
                    "type": "string",
                    "nullable": true,
                    "description": "Name of the product to transfer (alternative to productUUID)"
                  },
                  "productID": {
                    "type": "string",
                    "nullable": true,
                    "description": "ID of the product to transfer (alternative to productUUID)"
                  }
                },
                "anyOf": [
                  { "required": ["productUUID"] },
                  { "required": ["productName"] },
                  { "required": ["productID"] }
                ],
                "allOf": [
                  {
                    "oneOf": [
                      { "required": ["fromRobloxID"] },
                      { "required": ["fromDiscordID"] }
                    ]
                  },
                  {
                    "oneOf": [
                      { "required": ["toRobloxID"] },
                      { "required": ["toDiscordID"] }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License transferred successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "License transferred successfully"
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["message", "error"]
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing fields, product not found, source account doesn't own license, or destination account already owns license",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/blacklists": {
      "get": {
        "summary": "Get Vault Blacklists",
        "description": "Returns all blacklists with the authenticated vault.",
        "tags": ["Blacklists"],
        "security": [{ "vaultDevAuth": [] }],
        "responses": {
          "200": {
            "description": "Successful response with list of blacklists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "blacklistUUID": { "type": "string" },
                          "robloxID": { "type": "string" },
                          "robloxUsername": { "type": "string" },
                          "type": { "type": "string" },
                          "reason": { "type": "string" },
                          "staffUsername": { "type": "string" },
                          "staffID": { "type": "string" },
                          "groupID": { "type": "string" },
                          "timestamp": { "type": "string" }
                        }
                      }
                    },
                    "error": { "type": "boolean", "example": false }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/blacklists/add": {
      "post": {
        "summary": "Add Blacklist",
        "description": "Adds a blacklists to the vault for an account.",
        "tags": ["Blacklists"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "description": "Blacklist information",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "robloxID": { "type": "string", "nullable": true },
                  "reason": { "type": "string" }
                },
                "required": ["robloxID", "reason"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Blacklist added successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Blacklist added successfully"
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["message", "error"]
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing fields or blacklist already exists",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/blacklists/delete": {
      "delete": {
        "summary": "Delete Blacklist from Account",
        "description": "Deletes a blacklist from the vault for an account.",
        "tags": ["Blacklists"],
        "security": [{ "vaultDevAuth": [] }],
        "requestBody": {
          "description": "Blacklist deletion parameters",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "robloxID": { "type": "string", "nullable": true }
                },
                "required": ["robloxID"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Blacklist deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Blacklist deleted successfully"
                    },
                    "error": { "type": "boolean", "example": false }
                  },
                  "required": ["message", "error"]
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to missing fields or blacklist issues",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/vault/reviews": {
      "get": {
        "summary": "Get Vault Reviews",
        "description": "Returns paginated review history for the authenticated vault.",
        "tags": ["Vault"],
        "security": [{ "vaultDevAuth": [] }],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 8
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response with paginated list of reviews",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "reviews": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "reviewUUID": { "type": "string" },
                              "productUUID": { "type": "string" },
                              "robloxID": { "type": "string" },
                              "robloxUsername": { "type": "string" },
                              "discordID": { "type": "string" },
                              "discordUsername": { "type": "string" },
                              "rating": { "type": "number" },
                              "comment": { "type": "string" },
                              "timestamp": { "type": "string" }
                            }
                          }
                        },
                        "page": {
                          "type": "integer",
                          "description": "Current page number"
                        },
                        "limit": {
                          "type": "integer",
                          "description": "Items per page"
                        },
                        "totalCount": {
                          "type": "integer",
                          "description": "Total number of reviews"
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "Total number of pages"
                        },
                        "hasNextPage": {
                          "type": "boolean",
                          "description": "Whether there is a next page"
                        },
                        "hasPreviousPage": {
                          "type": "boolean",
                          "description": "Whether there is a previous page"
                        }
                      }
                    },
                    "error": { "type": "boolean", "example": false }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to invalid pagination parameters",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/api/developers/vault/alerts": {
      "get": {
        "summary": "Get Vault Alerts",
        "description": "Returns paginated alert history for the authenticated vault.",
        "tags": ["Vault"],
        "security": [{ "vaultDevAuth": [] }],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 8
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response with paginated list of alerts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "alerts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "alertUUID": { "type": "string" },
                              "productUUID": { "type": "string" },
                              "gameID": { "type": "string" },
                              "ownerID": { "type": "string" },
                              "ownerUsername": { "type": "string" },
                              "placeID": { "type": "string" },
                              "timestamp": { "type": "string" }
                            }
                          }
                        },
                        "page": {
                          "type": "integer",
                          "description": "Current page number"
                        },
                        "limit": {
                          "type": "integer",
                          "description": "Items per page"
                        },
                        "totalCount": {
                          "type": "integer",
                          "description": "Total number of alerts"
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "Total number of pages"
                        },
                        "hasNextPage": {
                          "type": "boolean",
                          "description": "Whether there is a next page"
                        },
                        "hasPreviousPage": {
                          "type": "boolean",
                          "description": "Whether there is a previous page"
                        }
                      }
                    },
                    "error": { "type": "boolean", "example": false }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request due to invalid pagination parameters",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "vaultDevAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "message": { "type": "string" },
          "error": { "type": "boolean", "example": true }
        },
        "required": ["message", "error"]
      }
    }
  },
  "tags": [
    { "name": "Vault", "description": "Vault related endpoints" },
    { "name": "Profile", "description": "Profile related endpoints" },
    { "name": "Licenses", "description": "Licenses related endpoints" },
    { "name": "Blacklists", "description": "Blacklists related endpoints" }
  ]
}
