{
  "openapi": "3.1.0",
  "info": {
    "title": "Relyo project API",
    "version": "1.0.0",
    "summary": "Create and manage Relyo co-browsing projects without an account.",
    "description": "POST /api/projects returns a public projectKey for the SDK and a secret manageToken. All other operations authenticate with `Authorization: Bearer <manageToken>`. The same operations are available as an MCP server at /mcp.",
    "license": {
      "name": "0BSD",
      "identifier": "0BSD"
    }
  },
  "externalDocs": {
    "url": "https://relyo.de/en/docs/project"
  },
  "servers": [
    {
      "url": "https://relyo.de"
    }
  ],
  "paths": {
    "/api/projects": {
      "post": {
        "operationId": "createProject",
        "summary": "Create a project",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created. manageToken is shown only once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid name or origins",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Sign-up disabled or address blocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many new projects from this address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Project limit of the server reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/project": {
      "get": {
        "operationId": "getProject",
        "summary": "Show the project of the manage token",
        "security": [
          {
            "manageToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unknown manage token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateProject",
        "summary": "Rename the project or replace its origins",
        "security": [
          {
            "manageToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "Invalid name or origins",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unknown manage token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteProject",
        "summary": "Delete the project; its key stops working immediately",
        "security": [
          {
            "manageToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "401": {
            "description": "Unknown manage token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/project/rotate-key": {
      "post": {
        "operationId": "rotateProjectKey",
        "summary": "Issue a new projectKey; the old one stops working, the manage token stays",
        "security": [
          {
            "manageToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Project with the new key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unknown manage token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "manageToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "manageToken (rpm_…) from POST /api/projects"
      }
    },
    "schemas": {
      "ProjectInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "origins": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "string",
              "format": "uri",
              "examples": [
                "https://example.com"
              ]
            },
            "description": "Web origins allowed to use the key. Native and Flutter apps send no origin and need none."
          }
        }
      },
      "ProjectUpdate": {
        "type": "object",
        "minProperties": 1,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "origins": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "string",
              "format": "uri"
            }
          }
        }
      },
      "Project": {
        "type": "object",
        "required": [
          "key",
          "name",
          "origins",
          "limits",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "key": {
            "type": "string",
            "pattern": "^pk_[0-9a-f]{20}$"
          },
          "name": {
            "type": "string"
          },
          "origins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "limits": {
            "type": "object",
            "properties": {
              "maxSessions": {
                "type": "integer",
                "description": "Concurrent sessions"
              },
              "maxSessionMinutes": {
                "type": "integer",
                "description": "0 = unlimited"
              },
              "idleMinutes": {
                "type": "integer",
                "description": "0 = off"
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreatedProject": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Project"
          },
          {
            "type": "object",
            "required": [
              "manageToken"
            ],
            "properties": {
              "manageToken": {
                "type": "string",
                "pattern": "^rpm_"
              }
            }
          }
        ]
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "bad_request",
              "unauthorized",
              "signup_disabled",
              "rate_limited",
              "blocked",
              "project_limit"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}
