{
  "openapi": "3.0.3",
  "info": {
    "title": "JustBrowser Automation API",
    "description": "REST API for managing browser profiles and integrating with Selenium, Playwright, and Puppeteer automation frameworks.",
    "version": "1.0.349"
  },
  "servers": [
    {
      "url": "http://127.0.0.1:36542/api/v1",
      "description": "Local API server"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API token from Settings > API"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "description": "Array of issue objects for VALIDATION_ERROR; an object for other errors that carry context"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        }
      },
      "Profile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "folder_id": {
            "type": "string",
            "nullable": true
          },
          "notes": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "stopped",
              "running",
              "error",
              "launching"
            ]
          },
          "consistency_score": {
            "type": "number",
            "nullable": true
          },
          "detection_score": {
            "type": "number",
            "nullable": true
          },
          "last_used_at": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Proxy": {
        "type": "object",
        "description": "Credentials are never returned. `has_credentials` says whether the proxy authenticates.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "protocol": {
            "type": "string",
            "enum": [
              "http",
              "https",
              "socks5"
            ]
          },
          "host": {
            "type": "string"
          },
          "port": {
            "type": "number"
          },
          "has_credentials": {
            "type": "boolean"
          },
          "country_code": {
            "type": "string",
            "nullable": true
          },
          "geo_country": {
            "type": "string",
            "nullable": true
          },
          "geo_city": {
            "type": "string",
            "nullable": true
          },
          "geo_timezone": {
            "type": "string",
            "nullable": true
          },
          "last_status": {
            "type": "string",
            "enum": [
              "untested",
              "connected",
              "failed"
            ]
          },
          "last_latency_ms": {
            "type": "number",
            "nullable": true
          },
          "last_tested_at": {
            "type": "string",
            "nullable": true
          },
          "assigned_profile_count": {
            "type": "number"
          }
        }
      }
    }
  },
  "paths": {
    "/profiles": {
      "get": {
        "summary": "List profiles",
        "description": "List all profiles with optional filters",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search by profile name"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "stopped",
                "running",
                "error",
                "launching"
              ]
            }
          },
          {
            "name": "folder_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "status",
                "last_used_at",
                "detection_score",
                "created_at"
              ],
              "default": "created_at"
            }
          },
          {
            "name": "sort_direction",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "profiles": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Profile"
                          }
                        },
                        "total": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "PROFILES"
        ]
      },
      "post": {
        "summary": "Create a profile",
        "description": "Create a new browser profile with full configuration",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "Profile name"
                  },
                  "folder_id": {
                    "type": "string",
                    "description": "Folder ID to assign"
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 5000,
                    "description": "Profile notes"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Profile created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Profile"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "PROFILES"
        ]
      }
    },
    "/profiles/{id}": {
      "get": {
        "summary": "Get a profile",
        "description": "Get a single profile by ID",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile details"
          },
          "404": {
            "description": "Profile not found"
          }
        },
        "tags": [
          "PROFILES"
        ]
      },
      "put": {
        "summary": "Update a profile",
        "description": "Update an existing profile",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "folder_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profile updated"
          },
          "404": {
            "description": "Profile not found"
          }
        },
        "tags": [
          "PROFILES"
        ]
      },
      "delete": {
        "summary": "Delete a profile",
        "description": "Delete a profile. Cannot delete a running profile — stop the browser first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile deleted"
          },
          "404": {
            "description": "Profile not found"
          },
          "409": {
            "description": "Profile is running"
          }
        },
        "tags": [
          "PROFILES"
        ]
      }
    },
    "/profiles/{id}/start": {
      "post": {
        "summary": "Start a profile browser",
        "description": "Launch a browser instance for a profile and return the CDP WebSocket URL for automation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "headless": {
                    "type": "boolean",
                    "default": true,
                    "description": "Launch in headless mode (default: true for API)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Browser launched",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "profile_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "running"
                          ]
                        },
                        "cdp_url": {
                          "type": "string",
                          "description": "CDP WebSocket URL — use with Playwright connectOverCDP() or Puppeteer connect()"
                        },
                        "launched_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Profile has no fingerprint"
          },
          "404": {
            "description": "Profile not found"
          },
          "409": {
            "description": "Profile already running"
          },
          "429": {
            "description": "Max concurrent profiles reached"
          }
        },
        "tags": [
          "RUNNING A BROWSER"
        ]
      }
    },
    "/profiles/{id}/stop": {
      "post": {
        "summary": "Stop a profile browser",
        "description": "Stop a running browser instance for a profile.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Browser stopped",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "profile_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "stopped"
                          ]
                        },
                        "stopped_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Profile not running"
          }
        },
        "tags": [
          "RUNNING A BROWSER"
        ]
      }
    },
    "/profiles/{id}/cdp": {
      "get": {
        "summary": "Get CDP WebSocket URL",
        "description": "Get the Chrome DevTools Protocol WebSocket URL for a running profile. Use this URL with Playwright chromium.connectOverCDP() or Puppeteer puppeteer.connect().",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CDP connection info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "profile_id": {
                          "type": "string"
                        },
                        "cdp_url": {
                          "type": "string"
                        },
                        "browser": {
                          "type": "object",
                          "properties": {
                            "running": {
                              "type": "boolean"
                            },
                            "pid": {
                              "type": "number"
                            },
                            "launched_at": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Profile not running"
          }
        },
        "tags": [
          "RUNNING A BROWSER"
        ]
      }
    },
    "/profiles/{id}/selenium": {
      "get": {
        "summary": "Get Selenium connection info",
        "description": "Get Selenium RemoteWebDriver-compatible connection info for a running profile. Returns the debugger address and Chrome capabilities needed for Selenium integration.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Selenium connection info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "profile_id": {
                          "type": "string"
                        },
                        "cdp_url": {
                          "type": "string"
                        },
                        "selenium": {
                          "type": "object",
                          "properties": {
                            "remote_url": {
                              "type": "string",
                              "description": "The DevTools HTTP endpoint (http://127.0.0.1:PORT), not a Selenium Grid / RemoteWebDriver URL — attach with the debuggerAddress capability"
                            },
                            "debugger_address": {
                              "type": "string",
                              "description": "Chrome debugger address (host:port)"
                            },
                            "capabilities": {
                              "type": "object",
                              "description": "Chrome capabilities for WebDriver"
                            }
                          }
                        },
                        "browser": {
                          "type": "object",
                          "properties": {
                            "running": {
                              "type": "boolean"
                            },
                            "pid": {
                              "type": "number"
                            },
                            "launched_at": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Profile not running"
          }
        },
        "tags": [
          "RUNNING A BROWSER"
        ]
      }
    },
    "/profiles/{id}/status": {
      "get": {
        "summary": "Get profile runtime status",
        "description": "Get the current runtime status of a profile including browser and proxy info.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile status"
          },
          "404": {
            "description": "Profile not found"
          }
        },
        "tags": [
          "PROFILES"
        ]
      }
    },
    "/profiles/batch/start": {
      "post": {
        "summary": "Start several profiles",
        "description": "Launch a set of profiles in one call, respecting the concurrency limit. Prefer this over N calls to /profiles/{id}/start.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_ids"
                ],
                "properties": {
                  "profile_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "headless": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-profile launch results"
          }
        },
        "tags": [
          "BATCH"
        ]
      }
    },
    "/profiles/batch/stop": {
      "post": {
        "summary": "Stop several profiles",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_ids"
                ],
                "properties": {
                  "profile_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-profile stop results"
          }
        },
        "tags": [
          "BATCH"
        ]
      }
    },
    "/profiles/{id}/fingerprint": {
      "get": {
        "summary": "Get a profile fingerprint",
        "description": "The full spoof config applied at launch: platform, screen, hardware, WebGL, fonts, timezone, locale.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Fingerprint config"
          },
          "404": {
            "description": "Profile has no fingerprint"
          }
        },
        "tags": [
          "FINGERPRINT"
        ]
      },
      "post": {
        "summary": "Regenerate a fingerprint",
        "description": "Replaces the profile fingerprint with a freshly generated, internally consistent one. Every field is optional.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "os": {
                    "type": "string",
                    "enum": [
                      "windows",
                      "macos",
                      "linux"
                    ]
                  },
                  "browser": {
                    "type": "string",
                    "enum": [
                      "chrome",
                      "firefox"
                    ]
                  },
                  "locale": {
                    "type": "string",
                    "example": "en-US"
                  },
                  "device_type": {
                    "type": "string",
                    "enum": [
                      "desktop",
                      "mobile"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new fingerprint config"
          }
        },
        "tags": [
          "FINGERPRINT"
        ]
      }
    },
    "/profiles/{id}/fingerprint/validate": {
      "get": {
        "summary": "Check fingerprint consistency",
        "description": "Runs the consistency rules and returns a 0-100 score plus the failing rules. Worth calling after any fingerprint edit.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Score and issue list"
          }
        },
        "tags": [
          "FINGERPRINT"
        ]
      }
    },
    "/profiles/{id}/fingerprint/fix": {
      "post": {
        "summary": "Auto-fix fingerprint issues",
        "description": "Applies the automatic fix for every fixable rule reported by /validate.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Fixes applied"
          }
        },
        "tags": [
          "FINGERPRINT"
        ]
      }
    },
    "/proxies": {
      "get": {
        "summary": "List proxies",
        "responses": {
          "200": {
            "description": "Proxy list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "proxies": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Proxy"
                          }
                        },
                        "total": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "PROXIES"
        ]
      },
      "post": {
        "summary": "Create a proxy",
        "description": "Credentials are encrypted on write and never read back over this API.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "protocol",
                  "host",
                  "port"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "protocol": {
                    "type": "string",
                    "enum": [
                      "http",
                      "https",
                      "socks5"
                    ]
                  },
                  "host": {
                    "type": "string"
                  },
                  "port": {
                    "type": "number"
                  },
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created proxy"
          }
        },
        "tags": [
          "PROXIES"
        ]
      }
    },
    "/proxies/{id}": {
      "get": {
        "summary": "Get a proxy",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Proxy"
          }
        },
        "tags": [
          "PROXIES"
        ]
      },
      "put": {
        "summary": "Update a proxy",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Updated proxy"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "def": {
                  "type": "object",
                  "shape": {
                    "name": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string",
                            "checks": [
                              {}
                            ]
                          },
                          "type": "string",
                          "format": null,
                          "minLength": null,
                          "maxLength": 100
                        }
                      },
                      "type": "optional"
                    },
                    "protocol": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "enum",
                            "entries": {
                              "http": "http",
                              "https": "https",
                              "socks5": "socks5"
                            }
                          },
                          "type": "enum",
                          "enum": {
                            "http": "http",
                            "https": "https",
                            "socks5": "socks5"
                          },
                          "options": [
                            "http",
                            "https",
                            "socks5"
                          ]
                        }
                      },
                      "type": "optional"
                    },
                    "host": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string",
                            "checks": [
                              {}
                            ]
                          },
                          "type": "string",
                          "format": null,
                          "minLength": 1,
                          "maxLength": null
                        }
                      },
                      "type": "optional"
                    },
                    "port": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "number",
                            "checks": [
                              {
                                "def": {
                                  "type": "number",
                                  "check": "number_format",
                                  "abort": false,
                                  "format": "safeint"
                                },
                                "type": "number",
                                "minValue": -9007199254740991,
                                "maxValue": 9007199254740991,
                                "isInt": true,
                                "isFinite": true,
                                "format": "safeint"
                              },
                              {},
                              {}
                            ]
                          },
                          "type": "number",
                          "minValue": 1,
                          "maxValue": 65535,
                          "isInt": true,
                          "isFinite": true,
                          "format": "safeint"
                        }
                      },
                      "type": "optional"
                    },
                    "username": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string"
                          },
                          "type": "string",
                          "format": null,
                          "minLength": null,
                          "maxLength": null
                        }
                      },
                      "type": "optional"
                    },
                    "password": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string"
                          },
                          "type": "string",
                          "format": null,
                          "minLength": null,
                          "maxLength": null
                        }
                      },
                      "type": "optional"
                    }
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "tags": [
          "PROXIES"
        ]
      },
      "delete": {
        "summary": "Delete a proxy",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted"
          }
        },
        "tags": [
          "PROXIES"
        ]
      }
    },
    "/proxies/{id}/test": {
      "post": {
        "summary": "Test a proxy",
        "description": "Live connectivity check. Returns latency and the geo the upstream actually exits from — use it to confirm a proxy still matches its profile timezone.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Test result with latency, IP and geo"
          }
        },
        "tags": [
          "PROXIES"
        ]
      }
    },
    "/profiles/{id}/proxy": {
      "get": {
        "summary": "Get the proxy assigned to a profile",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assigned proxy, or null"
          }
        },
        "tags": [
          "PROXIES"
        ]
      },
      "put": {
        "summary": "Assign a proxy to a profile",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "proxy_id"
                ],
                "properties": {
                  "proxy_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The newly assigned proxy"
          }
        },
        "tags": [
          "PROXIES"
        ]
      }
    },
    "/tags": {
      "get": {
        "summary": "List tags",
        "responses": {
          "200": {
            "description": "Tag list"
          }
        },
        "tags": [
          "ORGANISATION"
        ]
      },
      "post": {
        "summary": "Create a tag",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created tag"
          }
        },
        "tags": [
          "ORGANISATION"
        ]
      }
    },
    "/profiles/{id}/tags": {
      "get": {
        "summary": "Get a profile's tags",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tag list"
          }
        },
        "tags": [
          "ORGANISATION"
        ]
      },
      "put": {
        "summary": "Replace a profile's tags",
        "description": "Sets the complete tag list — tags omitted here are removed.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tag_ids"
                ],
                "properties": {
                  "tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The resulting tag list"
          }
        },
        "tags": [
          "ORGANISATION"
        ]
      }
    },
    "/folders": {
      "get": {
        "summary": "List folders",
        "responses": {
          "200": {
            "description": "Folder list"
          }
        },
        "tags": [
          "ORGANISATION"
        ]
      },
      "post": {
        "summary": "Create a folder",
        "tags": [
          "ORGANISATION"
        ],
        "responses": {
          "200": {
            "description": "Create a folder"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "parent_id": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/system/status": {
      "get": {
        "summary": "System status",
        "description": "Get system status including running profile count and app version.",
        "responses": {
          "200": {
            "description": "System status info"
          }
        },
        "tags": [
          "META"
        ]
      }
    },
    "/docs": {
      "get": {
        "summary": "API documentation",
        "description": "Returns this OpenAPI-style JSON schema.",
        "responses": {
          "200": {
            "description": "OpenAPI schema"
          }
        },
        "tags": [
          "META"
        ]
      }
    },
    "/profiles/bulk": {
      "post": {
        "summary": "Create up to 100 from a naming pattern",
        "tags": [
          "PROFILES"
        ],
        "responses": {
          "200": {
            "description": "Create up to 100 from a naming pattern"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "count"
                ],
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100
                  },
                  "naming_pattern": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 90
                  },
                  "template_id": {
                    "type": "string"
                  },
                  "os": {
                    "type": "string",
                    "enum": [
                      "windows",
                      "macos",
                      "linux"
                    ]
                  },
                  "browser": {
                    "type": "string",
                    "enum": [
                      "chrome",
                      "firefox"
                    ]
                  },
                  "locale": {
                    "type": "string"
                  },
                  "device_type": {
                    "type": "string",
                    "enum": [
                      "desktop",
                      "mobile"
                    ]
                  },
                  "proxy_id": {
                    "type": "string"
                  },
                  "folder_id": {
                    "type": "string"
                  },
                  "tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/batch/delete": {
      "post": {
        "summary": "Delete many",
        "tags": [
          "BATCH"
        ],
        "responses": {
          "200": {
            "description": "Delete many"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_ids"
                ],
                "properties": {
                  "profile_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/batch/tag": {
      "post": {
        "summary": "Add/remove one tag across many",
        "tags": [
          "BATCH"
        ],
        "responses": {
          "200": {
            "description": "Add/remove one tag across many"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_ids",
                  "tag_id",
                  "action"
                ],
                "properties": {
                  "profile_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  },
                  "tag_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "add",
                      "remove"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/batch/move": {
      "post": {
        "summary": "Move many into a folder",
        "tags": [
          "BATCH"
        ],
        "responses": {
          "200": {
            "description": "Move many into a folder"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_ids"
                ],
                "properties": {
                  "profile_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  },
                  "folder_id": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/batch/proxy": {
      "post": {
        "summary": "Spread a proxy pool across many",
        "tags": [
          "BATCH"
        ],
        "responses": {
          "200": {
            "description": "Spread a proxy pool across many"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_ids",
                  "proxy_ids"
                ],
                "properties": {
                  "profile_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  },
                  "proxy_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string"
                    }
                  },
                  "strategy": {
                    "type": "string",
                    "enum": [
                      "round-robin",
                      "random"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates": {
      "get": {
        "summary": "Saved fingerprint templates + presets",
        "tags": [
          "FINGERPRINT"
        ],
        "responses": {
          "200": {
            "description": "Saved fingerprint templates + presets"
          }
        }
      }
    },
    "/templates/{id}": {
      "get": {
        "summary": "One template",
        "tags": [
          "FINGERPRINT"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One template"
          }
        }
      },
      "delete": {
        "summary": "Delete a template",
        "tags": [
          "ORGANISATION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delete a template"
          }
        }
      }
    },
    "/profiles/{id}/template": {
      "post": {
        "summary": "Apply a template (body: template_id)",
        "tags": [
          "FINGERPRINT"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Apply a template (body: template_id)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "template_id"
                ],
                "properties": {
                  "template_id": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{id}/template/save": {
      "post": {
        "summary": "Save this profile's shape as a template",
        "tags": [
          "FINGERPRINT"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Save this profile's shape as a template"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{id}/detection": {
      "post": {
        "summary": "Run the 18-vector suite (slow, launches a browser)",
        "tags": [
          "DETECTION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run the 18-vector suite (slow, launches a browser)"
          }
        }
      },
      "get": {
        "summary": "Latest result",
        "tags": [
          "DETECTION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Latest result"
          }
        }
      }
    },
    "/profiles/{id}/detection/history": {
      "get": {
        "summary": "Previous runs (?limit=)",
        "tags": [
          "DETECTION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Previous runs (?limit=)"
          }
        }
      }
    },
    "/profiles/{id}/detection/fix": {
      "post": {
        "summary": "Auto-fix every fixable vector",
        "tags": [
          "DETECTION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Auto-fix every fixable vector"
          }
        }
      }
    },
    "/profiles/{id}/detection/fix/{vector}": {
      "post": {
        "summary": "Auto-fix one vector",
        "tags": [
          "DETECTION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vector",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Auto-fix one vector"
          }
        }
      }
    },
    "/profiles/{id}/health": {
      "get": {
        "summary": "Composite health score",
        "tags": [
          "DETECTION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Composite health score"
          }
        }
      }
    },
    "/profiles/{id}/cookies": {
      "post": {
        "summary": "Import (body: cookies[] or content)",
        "tags": [
          "COOKIES"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Import (body: cookies[] or content)"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cookies": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "content": {
                    "type": "string"
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "json",
                      "netscape",
                      "auto"
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Export the profile's cookies",
        "tags": [
          "COOKIES"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Export the profile's cookies"
          }
        }
      }
    },
    "/profiles/{id}/warmup": {
      "post": {
        "summary": "Start (runs visibly, minutes)",
        "tags": [
          "WARMUP"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Start (runs visibly, minutes)"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": [
                  "object",
                  "null"
                ]
              }
            }
          }
        }
      },
      "get": {
        "summary": "Progress of a run",
        "tags": [
          "WARMUP"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Progress of a run"
          }
        }
      },
      "delete": {
        "summary": "Stop a run",
        "tags": [
          "WARMUP"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stop a run"
          }
        }
      }
    },
    "/chromium/versions": {
      "get": {
        "summary": "Cores in the registry",
        "tags": [
          "PROFILE CONFIG"
        ],
        "responses": {
          "200": {
            "description": "Cores in the registry"
          }
        }
      }
    },
    "/profiles/{id}/chromium": {
      "get": {
        "summary": "Which core this profile pins",
        "tags": [
          "PROFILE CONFIG"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Which core this profile pins"
          }
        }
      },
      "post": {
        "summary": "Upgrade it (stop the profile first)",
        "tags": [
          "PROFILE CONFIG"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Upgrade it (stop the profile first)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "version"
                ],
                "properties": {
                  "version": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{id}/dns": {
      "get": {
        "summary": "DNS-over-HTTPS config",
        "tags": [
          "PROFILE CONFIG"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "DNS-over-HTTPS config"
          }
        }
      },
      "put": {
        "summary": "Set it",
        "tags": [
          "PROFILE CONFIG"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Set it"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "cloudflare",
                      "google",
                      "quad9",
                      "custom",
                      "disabled"
                    ]
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "automatic",
                      "secure",
                      "off"
                    ]
                  },
                  "custom_url": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/proxies/{id}/geo": {
      "get": {
        "summary": "Where a proxy actually exits",
        "tags": [
          "PROFILE CONFIG"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Where a proxy actually exits"
          }
        }
      }
    },
    "/profiles/{id}/geo-match": {
      "post": {
        "summary": "Check/apply fingerprint vs proxy geo",
        "tags": [
          "PROFILE CONFIG"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Check/apply fingerprint vs proxy geo"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "proxy_id"
                ],
                "properties": {
                  "proxy_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "apply": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{id}/export": {
      "post": {
        "summary": "Encrypted archive to a file path",
        "tags": [
          "BACKUP"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Encrypted archive to a file path"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_path",
                  "passphrase"
                ],
                "properties": {
                  "file_path": {
                    "type": "string",
                    "minLength": 1
                  },
                  "passphrase": {
                    "type": "string",
                    "minLength": 4
                  },
                  "include_user_data": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/import": {
      "post": {
        "summary": "Restore one from a file path",
        "tags": [
          "BACKUP"
        ],
        "responses": {
          "200": {
            "description": "Restore one from a file path"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_path",
                  "passphrase"
                ],
                "properties": {
                  "file_path": {
                    "type": "string",
                    "minLength": 1
                  },
                  "passphrase": {
                    "type": "string",
                    "minLength": 1
                  },
                  "new_name": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    "/folders/tree": {
      "get": {
        "summary": "Folders as a tree",
        "tags": [
          "ORGANISATION"
        ],
        "responses": {
          "200": {
            "description": "Folders as a tree"
          }
        }
      }
    },
    "/folders/{id}": {
      "put": {
        "summary": "Rename / move a folder",
        "tags": [
          "ORGANISATION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rename / move a folder"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "def": {
                  "type": "object",
                  "shape": {
                    "name": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string",
                            "checks": [
                              {},
                              {}
                            ]
                          },
                          "type": "string",
                          "format": null,
                          "minLength": 1,
                          "maxLength": 100
                        }
                      },
                      "type": "optional"
                    },
                    "parent_id": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "nullable",
                            "innerType": {
                              "def": {
                                "type": "string"
                              },
                              "type": "string",
                              "format": null,
                              "minLength": null,
                              "maxLength": null
                            }
                          },
                          "type": "nullable"
                        }
                      },
                      "type": "optional"
                    },
                    "sort_order": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "number",
                            "checks": [
                              {
                                "def": {
                                  "type": "number",
                                  "check": "number_format",
                                  "abort": false,
                                  "format": "safeint"
                                },
                                "type": "number",
                                "minValue": -9007199254740991,
                                "maxValue": 9007199254740991,
                                "isInt": true,
                                "isFinite": true,
                                "format": "safeint"
                              },
                              {}
                            ]
                          },
                          "type": "number",
                          "minValue": 0,
                          "maxValue": 9007199254740991,
                          "isInt": true,
                          "isFinite": true,
                          "format": "safeint"
                        }
                      },
                      "type": "optional"
                    }
                  }
                },
                "type": "object"
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a folder",
        "tags": [
          "ORGANISATION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delete a folder"
          }
        }
      }
    },
    "/tags/{id}": {
      "put": {
        "summary": "Rename / recolour a tag",
        "tags": [
          "ORGANISATION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rename / recolour a tag"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "def": {
                  "type": "object",
                  "shape": {
                    "name": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string",
                            "checks": [
                              {},
                              {}
                            ]
                          },
                          "type": "string",
                          "format": null,
                          "minLength": 1,
                          "maxLength": 50
                        }
                      },
                      "type": "optional"
                    },
                    "color": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string",
                            "checks": [
                              {}
                            ]
                          },
                          "type": "string",
                          "format": "regex",
                          "minLength": null,
                          "maxLength": null
                        }
                      },
                      "type": "optional"
                    }
                  }
                },
                "type": "object"
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a tag",
        "tags": [
          "ORGANISATION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delete a tag"
          }
        }
      }
    },
    "/profiles/{id}/duplicate": {
      "post": {
        "summary": "Clone a profile",
        "tags": [
          "ORGANISATION"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Clone a profile"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "copy_user_data": {
                    "type": "boolean"
                  },
                  "copy_proxy": {
                    "type": "boolean"
                  },
                  "regenerate_fingerprint": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{id}/logins": {
      "get": {
        "summary": "A profile's saved logins (no passwords)",
        "tags": [
          "LOGINS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A profile's saved logins (no passwords)"
          }
        }
      },
      "post": {
        "summary": "Save one",
        "tags": [
          "LOGINS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Save one"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "site_url",
                  "username",
                  "password"
                ],
                "properties": {
                  "site_url": {
                    "type": "string",
                    "minLength": 1
                  },
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/logins/{id}": {
      "put": {
        "summary": "Update one",
        "tags": [
          "LOGINS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Update one"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "site_url": {
                    "type": "string"
                  },
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete one",
        "tags": [
          "LOGINS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delete one"
          }
        }
      }
    },
    "/profiles/{id}/totp": {
      "delete": {
        "summary": "Remove the 2FA seed",
        "tags": [
          "LOGINS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Remove the 2FA seed"
          }
        }
      }
    },
    "/sync": {
      "get": {
        "summary": "Sync status of every profile",
        "tags": [
          "SYNC"
        ],
        "responses": {
          "200": {
            "description": "Sync status of every profile"
          }
        }
      }
    },
    "/profiles/{id}/sync": {
      "get": {
        "summary": "Sync status of one",
        "tags": [
          "SYNC"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sync status of one"
          }
        }
      },
      "post": {
        "summary": "Push it to the cloud now",
        "tags": [
          "SYNC"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Push it to the cloud now"
          }
        }
      }
    },
    "/sync/settings": {
      "get": {
        "summary": "Sync preferences",
        "tags": [
          "SYNC"
        ],
        "responses": {
          "200": {
            "description": "Sync preferences"
          }
        }
      },
      "put": {
        "summary": "Change them",
        "tags": [
          "SYNC"
        ],
        "responses": {
          "200": {
            "description": "Change them"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/profiles/{id}/lock": {
      "delete": {
        "summary": "Force-release a cross-device lock",
        "tags": [
          "SYNC"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Force-release a cross-device lock"
          }
        }
      }
    },
    "/teams": {
      "get": {
        "summary": "List teams",
        "tags": [
          "TEAMS"
        ],
        "responses": {
          "200": {
            "description": "List teams"
          }
        }
      },
      "post": {
        "summary": "Create one",
        "tags": [
          "TEAMS"
        ],
        "responses": {
          "200": {
            "description": "Create one"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/teams/{id}": {
      "put": {
        "summary": "Rename it",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rename it"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "def": {
                  "type": "object",
                  "shape": {
                    "name": {
                      "def": {
                        "type": "optional",
                        "innerType": {
                          "def": {
                            "type": "string",
                            "checks": [
                              {},
                              {}
                            ]
                          },
                          "type": "string",
                          "format": null,
                          "minLength": 1,
                          "maxLength": 100
                        }
                      },
                      "type": "optional"
                    }
                  }
                },
                "type": "object"
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete it",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delete it"
          }
        }
      }
    },
    "/teams/{id}/members": {
      "get": {
        "summary": "Members",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Members"
          }
        }
      },
      "post": {
        "summary": "Invite by email",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invite by email"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "minLength": 3
                  },
                  "role": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/teams/{id}/members/{memberId}": {
      "put": {
        "summary": "Change a role",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Change a role"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "role"
                ],
                "properties": {
                  "role": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove a member",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Remove a member"
          }
        }
      }
    },
    "/teams/{id}/profiles": {
      "get": {
        "summary": "Profiles shared with the team",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profiles shared with the team"
          }
        }
      },
      "post": {
        "summary": "Share one (push it first)",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Share one (push it first)"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "profile_id"
                ],
                "properties": {
                  "profile_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "profile_name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/teams/{id}/profiles/{sharedId}": {
      "delete": {
        "summary": "Unshare",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sharedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unshare"
          }
        }
      }
    },
    "/teams/{id}/invitations": {
      "get": {
        "summary": "Pending invitations",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending invitations"
          }
        }
      }
    },
    "/teams/{id}/invitations/{invitationId}": {
      "delete": {
        "summary": "Cancel one",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invitationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancel one"
          }
        }
      }
    },
    "/teams/{id}/activity": {
      "get": {
        "summary": "Team activity (?limit=)",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Team activity (?limit=)"
          }
        }
      }
    },
    "/shares": {
      "get": {
        "summary": "Direct shares in and out",
        "tags": [
          "TEAMS"
        ],
        "responses": {
          "200": {
            "description": "Direct shares in and out"
          }
        }
      }
    },
    "/shares/{id}": {
      "delete": {
        "summary": "Revoke one",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoke one"
          }
        }
      }
    },
    "/notifications": {
      "get": {
        "summary": "In-app notifications + unread count",
        "tags": [
          "TEAMS"
        ],
        "responses": {
          "200": {
            "description": "In-app notifications + unread count"
          }
        }
      }
    },
    "/notifications/{id}/read": {
      "post": {
        "summary": "Mark one read",
        "tags": [
          "TEAMS"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mark one read"
          }
        }
      }
    },
    "/notifications/read": {
      "post": {
        "summary": "Mark all read",
        "tags": [
          "TEAMS"
        ],
        "responses": {
          "200": {
            "description": "Mark all read"
          }
        }
      }
    },
    "/account/license": {
      "get": {
        "summary": "Plan, profile limit, feature flags",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Plan, profile limit, feature flags"
          }
        }
      }
    },
    "/settings": {
      "get": {
        "summary": "App settings (secrets redacted)",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "App settings (secrets redacted)"
          }
        }
      },
      "patch": {
        "summary": "Change settings (API-control keys refused)",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Change settings (API-control keys refused)"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/account": {
      "get": {
        "summary": "Signed-in user + auth status",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Signed-in user + auth status"
          }
        }
      }
    },
    "/account/license/refresh": {
      "post": {
        "summary": "Re-check entitlement",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Re-check entitlement"
          }
        }
      }
    },
    "/diagnostics": {
      "get": {
        "summary": "Chromium install, fingerprint data, stealth",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Chromium install, fingerprint data, stealth"
          }
        }
      }
    },
    "/diagnostics/fingerprint-data/refresh": {
      "post": {
        "summary": "Pull new generator data",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Pull new generator data"
          }
        }
      }
    },
    "/profiles/{id}/stealth/benchmark": {
      "post": {
        "summary": "Stealth benchmark run",
        "tags": [
          "META"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stealth benchmark run"
          }
        }
      }
    },
    "/proxy-market/products": {
      "get": {
        "summary": "Proxy catalogue (browse only)",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Proxy catalogue (browse only)"
          }
        }
      }
    },
    "/proxy-market/allocations": {
      "get": {
        "summary": "Proxies the account already owns",
        "tags": [
          "META"
        ],
        "responses": {
          "200": {
            "description": "Proxies the account already owns"
          }
        }
      }
    }
  }
}
