{
  "openapi": "3.1.0",
  "info": {
    "title": "Produktly API",
    "version": "1.0.0",
    "description": "The Produktly REST API gives you programmatic access to your product tours, checklists, smart tips, announcements, micro surveys, changelogs, roadmaps, feedback widgets, NPS widgets, tags, analytics, and identified users. It exposes the same functionality as the [MCP server](https://produktly.com/docs/mcp-server/), over plain HTTP.\n\n## Base URL\n\n```\nhttps://api.produktly.com/api/v1\n```\n\n## Authentication\n\nAll endpoints (except `GET /openapi.json`) require an API key passed as a Bearer token.\n\n1. Sign in to Produktly and open **Settings → [API keys](https://produktly.com/app/settings/private-keys)**.\n2. Generate a new key and copy it. The same key works for both REST and MCP.\n3. Send it on every request:\n\n```http\nGET /api/v1/changelogs HTTP/1.1\nHost: api.produktly.com\nAuthorization: Bearer <your-api-key>\n```\n\nMissing or invalid keys return `401 unauthorized`. Treat the key like a password — anyone with it can read and write your Produktly data.\n\nScopes, error codes, rotation, and how API keys differ from the public Client Auth Token are covered in the [API authentication guide](https://produktly.com/docs/docs/api/authentication).\n\n## Response format\n\nList endpoints return an envelope with a `data` array and `pagination` metadata:\n\n```json\n{\n  \"data\": [ { \"id\": 1, \"name\": \"...\" } ],\n  \"pagination\": { \"total\": 42, \"limit\": 50, \"offset\": 0 }\n}\n```\n\nSingle-resource endpoints (e.g. `GET /roadmaps/{id}`) return the resource directly, no envelope.\n\n## Pagination\n\nList endpoints accept `limit` (default 50, max 100) and `offset` (default 0) query parameters. Date filters (`startDate`, `endDate`) compose with pagination where supported.\n\n## Errors\n\nErrors come back in a consistent shape:\n\n```json\n{\n  \"error\": {\n    \"code\": \"invalid_tag_names\",\n    \"message\": \"Unknown tag names: foo. Use GET /v1/tags to see available tags.\",\n    \"details\": { \"missing\": [\"foo\"] }\n  }\n}\n```\n\nCommon codes:\n\n- `unauthorized` (401) — missing or invalid API key\n- `not_found` (404) — resource doesn't exist or doesn't belong to your company\n- `validation_error` (400) — invalid request parameters\n- `rate_limit_exceeded` (429) — see Rate limits below\n- `internal_error` (500) — server-side problem; safe to retry\n\n## Rate limits\n\nEvery API key is limited to **60 requests per minute**. The `/users` endpoints have a separate bucket of **300 requests per minute** to support backend syncs. Every response includes:\n\n- `X-RateLimit-Limit`: total allowed in the window\n- `X-RateLimit-Remaining`: remaining quota\n- `X-RateLimit-Reset`: Unix seconds when the bucket refills\n\nWhen you exceed the limit you'll get `429 rate_limit_exceeded` with a `Retry-After` header. Back off and retry."
  },
  "servers": [
    {
      "url": "https://api.produktly.com/api/v1"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Use an API key from the Produktly dashboard → Settings → API keys."
      }
    },
    "schemas": {
      "Changelog": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt"
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          }
        },
        "required": [
          "total",
          "limit",
          "offset"
        ]
      },
      "ChangelogList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Changelog"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": {}
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Tag": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "backgroundColor": {
            "type": [
              "string",
              "null"
            ]
          },
          "textColor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "backgroundColor",
          "textColor"
        ]
      },
      "ChangelogPost": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "active": {
            "type": "boolean"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          }
        },
        "required": [
          "id",
          "title",
          "description",
          "date",
          "active",
          "tags"
        ]
      },
      "ChangelogPostList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangelogPost"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "CreateChangelogPostBody": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1
          },
          "description": {
            "type": "string"
          },
          "date": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "tagNames": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "title"
        ]
      },
      "UpdateChangelogPostBody": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "date": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "tagNames": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "FeedbackWidget": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt"
        ]
      },
      "FeedbackWidgetList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FeedbackWidget"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "FeedbackResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "type": {
            "type": "string"
          },
          "optionName": {
            "type": [
              "string",
              "null"
            ]
          },
          "emoji": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "fromUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "type",
          "optionName",
          "emoji",
          "message",
          "email",
          "name",
          "fromUrl",
          "createdAt"
        ]
      },
      "FeedbackResponseList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FeedbackResponse"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "FeedbackWidgetDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "themeId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "settings": {
            "type": "object",
            "additionalProperties": {}
          },
          "rules": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "ruleLogicalOperator": {
            "type": [
              "string",
              "null"
            ]
          },
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "dashboardUrl": {
            "type": "string"
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId",
          "themeId",
          "settings",
          "rules",
          "ruleLogicalOperator",
          "options",
          "dashboardUrl"
        ]
      },
      "RoadmapItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "votesCount": {
            "type": "integer"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "tag": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Tag"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "votesCount",
          "updatedAt",
          "tag"
        ]
      },
      "RoadmapSection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoadmapItem"
            }
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "Roadmap": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "publicName": {
            "type": [
              "string",
              "null"
            ]
          },
          "active": {
            "type": "boolean"
          },
          "customDomain": {
            "type": [
              "string",
              "null"
            ]
          },
          "publicId": {
            "type": "string"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoadmapSection"
            }
          }
        },
        "required": [
          "id",
          "name",
          "publicName",
          "active",
          "customDomain",
          "publicId"
        ]
      },
      "RoadmapList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Roadmap"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "NpsWidget": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt"
        ]
      },
      "NpsWidgetList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NpsWidget"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "NpsScore": {
        "type": "object",
        "properties": {
          "npsScore": {
            "type": "number"
          },
          "totalResponses": {
            "type": "integer"
          },
          "promoters": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "percentage": {
                "type": "number"
              }
            },
            "required": [
              "count",
              "percentage"
            ]
          },
          "passives": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "percentage": {
                "type": "number"
              }
            },
            "required": [
              "count",
              "percentage"
            ]
          },
          "detractors": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "percentage": {
                "type": "number"
              }
            },
            "required": [
              "count",
              "percentage"
            ]
          }
        },
        "required": [
          "npsScore",
          "totalResponses",
          "promoters",
          "passives",
          "detractors"
        ]
      },
      "NpsResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "rating": {
            "type": "string"
          },
          "comment": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "userId": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "language": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "rating",
          "comment",
          "email",
          "name",
          "userId",
          "url",
          "language",
          "createdAt"
        ]
      },
      "NpsResponseList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NpsResponse"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "NpsWidgetDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "themeId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "settings": {
            "type": "object",
            "additionalProperties": {}
          },
          "rules": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "ruleLogicalOperator": {
            "type": [
              "string",
              "null"
            ]
          },
          "dashboardUrl": {
            "type": "string"
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId",
          "themeId",
          "settings",
          "rules",
          "ruleLogicalOperator",
          "dashboardUrl"
        ]
      },
      "WidgetStats": {
        "type": "object",
        "properties": {
          "entityType": {
            "type": "string"
          },
          "period": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string"
              },
              "end": {
                "type": "string"
              }
            },
            "required": [
              "start",
              "end"
            ]
          },
          "widgets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "entityId": {
                  "type": "integer"
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "archivedAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "events": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "count": {
                        "type": "integer"
                      },
                      "uniqueUsers": {
                        "type": "integer"
                      }
                    },
                    "required": [
                      "count",
                      "uniqueUsers"
                    ]
                  }
                },
                "totalEvents": {
                  "type": "integer"
                },
                "totalUniqueUsers": {
                  "type": "integer"
                }
              },
              "required": [
                "entityId",
                "name",
                "archivedAt",
                "events",
                "totalEvents",
                "totalUniqueUsers"
              ]
            }
          }
        },
        "required": [
          "entityType",
          "period",
          "widgets"
        ]
      },
      "StatsSummary": {
        "type": "object",
        "properties": {
          "period": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string"
              },
              "end": {
                "type": "string"
              },
              "days": {
                "type": "integer"
              },
              "granularity": {
                "type": "string"
              }
            },
            "required": [
              "start",
              "end",
              "days",
              "granularity"
            ]
          },
          "previousPeriod": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string"
              },
              "end": {
                "type": "string"
              }
            },
            "required": [
              "start",
              "end"
            ]
          },
          "features": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "primary": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "previousCount": {
                      "type": "integer"
                    },
                    "changePct": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "label",
                    "count",
                    "previousCount",
                    "changePct"
                  ]
                },
                "secondary": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "value": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "previousValue": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "changePp": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "label",
                    "value",
                    "previousValue",
                    "changePp"
                  ]
                },
                "events": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "count": {
                        "type": "integer"
                      },
                      "uniqueUsers": {
                        "type": "integer"
                      },
                      "previousCount": {
                        "type": "integer"
                      },
                      "previousUniqueUsers": {
                        "type": "integer"
                      }
                    },
                    "required": [
                      "count",
                      "uniqueUsers",
                      "previousCount",
                      "previousUniqueUsers"
                    ]
                  }
                },
                "trend": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "period": {
                        "type": "string"
                      },
                      "count": {
                        "type": "integer"
                      }
                    },
                    "required": [
                      "period",
                      "count"
                    ]
                  }
                }
              },
              "required": [
                "type",
                "label",
                "primary",
                "secondary",
                "events",
                "trend"
              ]
            }
          }
        },
        "required": [
          "period",
          "previousPeriod",
          "features"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string"
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {}
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "userId",
          "metadata",
          "createdAt",
          "updatedAt"
        ]
      },
      "TagList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "ProductTourSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId"
        ]
      },
      "ProductTourList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductTourSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "ProductTour": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ProductTourSummary"
          },
          {
            "type": "object",
            "properties": {
              "themeId": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "settings": {
                "type": "object",
                "additionalProperties": {}
              },
              "rules": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "ruleLogicalOperator": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "dashboardUrl": {
                "type": "string"
              },
              "note": {
                "type": "string"
              }
            },
            "required": [
              "themeId",
              "steps",
              "settings",
              "rules",
              "ruleLogicalOperator",
              "dashboardUrl"
            ]
          }
        ]
      },
      "ChecklistSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId"
        ]
      },
      "ChecklistList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChecklistSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "Checklist": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ChecklistSummary"
          },
          {
            "type": "object",
            "properties": {
              "themeId": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "settings": {
                "type": "object",
                "additionalProperties": {}
              },
              "rules": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "ruleLogicalOperator": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "dashboardUrl": {
                "type": "string"
              },
              "note": {
                "type": "string"
              }
            },
            "required": [
              "themeId",
              "items",
              "settings",
              "rules",
              "ruleLogicalOperator",
              "dashboardUrl"
            ]
          }
        ]
      },
      "SmartTipSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId"
        ]
      },
      "SmartTipList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SmartTipSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "SmartTip": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SmartTipSummary"
          },
          {
            "type": "object",
            "properties": {
              "themeId": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "content": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "settings": {
                "type": "object",
                "additionalProperties": {}
              },
              "rules": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "ruleLogicalOperator": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "dashboardUrl": {
                "type": "string"
              },
              "note": {
                "type": "string"
              }
            },
            "required": [
              "themeId",
              "title",
              "content",
              "settings",
              "rules",
              "ruleLogicalOperator",
              "dashboardUrl"
            ]
          }
        ]
      },
      "AnnouncementSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId"
        ]
      },
      "AnnouncementList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnouncementSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "Announcement": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnnouncementSummary"
          },
          {
            "type": "object",
            "properties": {
              "themeId": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "content": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "settings": {
                "type": "object",
                "additionalProperties": {}
              },
              "rules": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "ruleLogicalOperator": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "dashboardUrl": {
                "type": "string"
              },
              "note": {
                "type": "string"
              }
            },
            "required": [
              "themeId",
              "title",
              "content",
              "settings",
              "rules",
              "ruleLogicalOperator",
              "dashboardUrl"
            ]
          }
        ]
      },
      "MicroSurveySummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folderId": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "active",
          "createdAt",
          "updatedAt",
          "folderId"
        ]
      },
      "MicroSurveyList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MicroSurveySummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "MicroSurvey": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MicroSurveySummary"
          },
          {
            "type": "object",
            "properties": {
              "themeId": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "settings": {
                "type": "object",
                "additionalProperties": {}
              },
              "rules": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "ruleLogicalOperator": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "dashboardUrl": {
                "type": "string"
              },
              "note": {
                "type": "string"
              }
            },
            "required": [
              "themeId",
              "settings",
              "rules",
              "ruleLogicalOperator",
              "dashboardUrl"
            ]
          }
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/changelogs": {
      "get": {
        "summary": "List changelogs",
        "tags": [
          "Changelogs"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of changelogs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangelogList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/changelogs/{changelogId}/posts": {
      "get": {
        "summary": "List posts in a changelog",
        "tags": [
          "Changelogs"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "changelogId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "default": 0
            },
            "required": false,
            "name": "offset",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List of posts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangelogPostList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a changelog post",
        "tags": [
          "Changelogs"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "changelogId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChangelogPostBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangelogPost"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/changelogs/{changelogId}/posts/{postId}": {
      "patch": {
        "summary": "Update a changelog post",
        "tags": [
          "Changelogs"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "changelogId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "postId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChangelogPostBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangelogPost"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/feedback-widgets": {
      "get": {
        "summary": "List feedback widgets",
        "tags": [
          "Feedback Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of feedback widgets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackWidgetList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a feedback widget",
        "description": "Creates the widget as a draft. Pass active: true to publish immediately — the widget must have at least one option and targeting set, otherwise it stays a draft and the response note explains why. Supply options directly or use optionsPreset for a built-in set. The response includes a dashboardUrl for reviewing the widget in the builder.",
        "tags": [
          "Feedback Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "options": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Shown under the emoji and submitted as optionName"
                        },
                        "emoji": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "description": "Submitted as the response type. Defaults to a slug of name"
                        }
                      },
                      "required": [
                        "name"
                      ],
                      "additionalProperties": false
                    },
                    "description": "The answer options users pick from"
                  },
                  "optionsPreset": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 6,
                    "description": "Use a built-in option set instead of listing options: 1 issue/idea/other, 2 three emojis, 3 five emojis, 4 four emojis, 5 feelings, 6 issue/idea/happy/angry/other"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "question": {
                        "type": "string",
                        "description": "Default \"We would love to hear your feedback\""
                      },
                      "showBeacon": {
                        "type": "boolean",
                        "description": "Default true. When false, open with Produktly.openFeedback()"
                      },
                      "collapsedText": {
                        "type": "string",
                        "description": "Beacon label. Default \"Feedback\""
                      },
                      "beaconLocation": {
                        "type": "string",
                        "enum": [
                          "mid-right",
                          "mid-left",
                          "bottom-right",
                          "bottom-left",
                          "right-bottom",
                          "left-bottom",
                          "top-right",
                          "top-left",
                          "right-top",
                          "left-top"
                        ],
                        "description": "Default \"mid-right\""
                      },
                      "collectEmail": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "emailOptional": {
                        "type": "boolean"
                      },
                      "shouldValidateEmail": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "allowScreenshots": {
                        "type": "boolean"
                      },
                      "autoCaptureScreenshot": {
                        "type": "boolean"
                      },
                      "requireScreenshot": {
                        "type": "boolean",
                        "description": "Only enforced when allowScreenshots is on and autoCaptureScreenshot is off"
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "emailLabelText": {
                        "type": "string"
                      },
                      "emailOptionalLabelText": {
                        "type": "string"
                      },
                      "messageLabelText": {
                        "type": "string"
                      },
                      "submitBtnText": {
                        "type": "string"
                      },
                      "submitAnotherBtnText": {
                        "type": "string"
                      },
                      "feedbackSuccessText": {
                        "type": "string"
                      },
                      "feedbackErrorText": {
                        "type": "string"
                      },
                      "emailMissingErrorText": {
                        "type": "string"
                      },
                      "emailInvalidErrorText": {
                        "type": "string"
                      },
                      "messageMissingErrorText": {
                        "type": "string"
                      },
                      "screenshotLabelText": {
                        "type": "string"
                      },
                      "screenshotMissingErrorText": {
                        "type": "string"
                      },
                      "slackWebhookUrl": {
                        "type": "string",
                        "description": "Write-only. Never returned by read endpoints"
                      },
                      "discordWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "zapierWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "customWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "notificationEmails": {
                        "type": "string",
                        "description": "Comma-separated. Write-only"
                      }
                    },
                    "additionalProperties": false
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. Needs at least one option and targeting"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created feedback widget",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackWidgetDetail"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/feedback-widgets/{widgetId}/responses": {
      "get": {
        "summary": "List feedback responses",
        "tags": [
          "Feedback Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "default": 0
            },
            "required": false,
            "name": "offset",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List of responses",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackResponseList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/feedback-widgets/{widgetId}": {
      "get": {
        "summary": "Get a feedback widget",
        "tags": [
          "Feedback Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The feedback widget",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackWidgetDetail"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a feedback widget",
        "description": "Only the fields you send are changed. settings are merged over stored settings; targeting and options (whether passed directly or via optionsPreset) replace wholesale. Live widgets can be edited, but an update that would leave one unpublishable (no options or no targeting) returns 400; set active: false first to take it down.",
        "tags": [
          "Feedback Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "options": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Shown under the emoji and submitted as optionName"
                        },
                        "emoji": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "description": "Submitted as the response type. Defaults to a slug of name"
                        }
                      },
                      "required": [
                        "name"
                      ],
                      "additionalProperties": false
                    },
                    "description": "Replaces all options"
                  },
                  "optionsPreset": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 6
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "question": {
                        "type": "string",
                        "description": "Default \"We would love to hear your feedback\""
                      },
                      "showBeacon": {
                        "type": "boolean",
                        "description": "Default true. When false, open with Produktly.openFeedback()"
                      },
                      "collapsedText": {
                        "type": "string",
                        "description": "Beacon label. Default \"Feedback\""
                      },
                      "beaconLocation": {
                        "type": "string",
                        "enum": [
                          "mid-right",
                          "mid-left",
                          "bottom-right",
                          "bottom-left",
                          "right-bottom",
                          "left-bottom",
                          "top-right",
                          "top-left",
                          "right-top",
                          "left-top"
                        ],
                        "description": "Default \"mid-right\""
                      },
                      "collectEmail": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "emailOptional": {
                        "type": "boolean"
                      },
                      "shouldValidateEmail": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "allowScreenshots": {
                        "type": "boolean"
                      },
                      "autoCaptureScreenshot": {
                        "type": "boolean"
                      },
                      "requireScreenshot": {
                        "type": "boolean",
                        "description": "Only enforced when allowScreenshots is on and autoCaptureScreenshot is off"
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "emailLabelText": {
                        "type": "string"
                      },
                      "emailOptionalLabelText": {
                        "type": "string"
                      },
                      "messageLabelText": {
                        "type": "string"
                      },
                      "submitBtnText": {
                        "type": "string"
                      },
                      "submitAnotherBtnText": {
                        "type": "string"
                      },
                      "feedbackSuccessText": {
                        "type": "string"
                      },
                      "feedbackErrorText": {
                        "type": "string"
                      },
                      "emailMissingErrorText": {
                        "type": "string"
                      },
                      "emailInvalidErrorText": {
                        "type": "string"
                      },
                      "messageMissingErrorText": {
                        "type": "string"
                      },
                      "screenshotLabelText": {
                        "type": "string"
                      },
                      "screenshotMissingErrorText": {
                        "type": "string"
                      },
                      "slackWebhookUrl": {
                        "type": "string",
                        "description": "Write-only. Never returned by read endpoints"
                      },
                      "discordWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "zapierWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "customWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "notificationEmails": {
                        "type": "string",
                        "description": "Comma-separated. Write-only"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackWidgetDetail"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published feedback widget",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/roadmaps": {
      "get": {
        "summary": "List roadmaps",
        "tags": [
          "Roadmaps"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of roadmaps",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoadmapList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/roadmaps/{roadmapId}": {
      "get": {
        "summary": "Get roadmap with sections and items",
        "tags": [
          "Roadmaps"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "roadmapId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100
            },
            "required": false,
            "name": "latestCount",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "query",
            "in": "query"
          },
          {
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "required": false,
            "name": "tagNames",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Roadmap",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Roadmap"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/nps-widgets": {
      "get": {
        "summary": "List NPS widgets",
        "tags": [
          "NPS Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of NPS widgets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWidgetList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create an NPS widget",
        "description": "Creates the widget as a draft. Pass active: true to publish immediately — the widget must have targeting set, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the widget in the builder.",
        "tags": [
          "NPS Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "selectedScale": {
                        "type": "string",
                        "enum": [
                          "ten",
                          "five",
                          "emojis"
                        ],
                        "description": "Rating scale. Default \"ten\" (0-10). \"five\" is 1-5, \"emojis\" is 0-2"
                      },
                      "title": {
                        "type": "string",
                        "description": "The question. Default \"How likely are you to recommend us?\""
                      },
                      "scaleLabelLeastLikely": {
                        "type": "string"
                      },
                      "scaleLabelMostLikely": {
                        "type": "string"
                      },
                      "collectEmail": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "emailRequired": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "shouldValidateEmail": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "emailText": {
                        "type": "string"
                      },
                      "emailMissingErrorText": {
                        "type": "string"
                      },
                      "emailInvalidErrorText": {
                        "type": "string"
                      },
                      "collectFeedback": {
                        "type": "boolean",
                        "description": "Show the follow-up comment box. Default true"
                      },
                      "msgText": {
                        "type": "string",
                        "description": "The follow-up question"
                      },
                      "msgPlaceholderText": {
                        "type": "string"
                      },
                      "submitBtnText": {
                        "type": "string"
                      },
                      "successText": {
                        "type": "string"
                      },
                      "closeBtnText": {
                        "type": "string"
                      },
                      "displayType": {
                        "type": "string",
                        "enum": [
                          "bottombar",
                          "bottombar-hovering",
                          "toast-left",
                          "toast-right"
                        ]
                      },
                      "displayTrigger": {
                        "type": "string",
                        "enum": [
                          "element_click",
                          "element_visible",
                          "immediate",
                          "time_on_page",
                          "manual"
                        ],
                        "description": "Default \"immediate\""
                      },
                      "displayTriggerTime": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Seconds, required for \"time_on_page\""
                      },
                      "displayTriggerSelector": {
                        "type": "string",
                        "description": "Required for element_click and element_visible"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "once_a_month",
                          "once_a_quarter",
                          "once_a_year",
                          "once_a_week",
                          "once",
                          "always"
                        ],
                        "description": "How often the same user is asked. Default \"once_a_month\""
                      },
                      "dismissOn": {
                        "type": "string",
                        "enum": [
                          "cross_click",
                          "never"
                        ]
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "slackWebhookUrl": {
                        "type": "string",
                        "description": "Write-only. Never returned by read endpoints"
                      },
                      "discordWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "zapierWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "customWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "notificationEmails": {
                        "type": "string",
                        "description": "Comma-separated. Write-only"
                      }
                    },
                    "additionalProperties": false
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. Needs targeting"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created NPS widget",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWidgetDetail"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/nps-widgets/{widgetId}/score": {
      "get": {
        "summary": "Get NPS score breakdown",
        "tags": [
          "NPS Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "NPS score",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsScore"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/nps-widgets/{widgetId}/responses": {
      "get": {
        "summary": "List NPS responses",
        "tags": [
          "NPS Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "default": 0
            },
            "required": false,
            "name": "offset",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List of NPS responses",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsResponseList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/nps-widgets/{widgetId}": {
      "get": {
        "summary": "Get an NPS widget",
        "tags": [
          "NPS Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The NPS widget",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWidgetDetail"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update an NPS widget",
        "description": "Only the fields you send are changed. settings are merged over stored settings; targeting replaces wholesale. Live widgets can be edited, but an update that would leave one unpublishable (no targeting) returns 400; set active: false first to take it down.",
        "tags": [
          "NPS Widgets"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "widgetId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "selectedScale": {
                        "type": "string",
                        "enum": [
                          "ten",
                          "five",
                          "emojis"
                        ],
                        "description": "Rating scale. Default \"ten\" (0-10). \"five\" is 1-5, \"emojis\" is 0-2"
                      },
                      "title": {
                        "type": "string",
                        "description": "The question. Default \"How likely are you to recommend us?\""
                      },
                      "scaleLabelLeastLikely": {
                        "type": "string"
                      },
                      "scaleLabelMostLikely": {
                        "type": "string"
                      },
                      "collectEmail": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "emailRequired": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "shouldValidateEmail": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "emailText": {
                        "type": "string"
                      },
                      "emailMissingErrorText": {
                        "type": "string"
                      },
                      "emailInvalidErrorText": {
                        "type": "string"
                      },
                      "collectFeedback": {
                        "type": "boolean",
                        "description": "Show the follow-up comment box. Default true"
                      },
                      "msgText": {
                        "type": "string",
                        "description": "The follow-up question"
                      },
                      "msgPlaceholderText": {
                        "type": "string"
                      },
                      "submitBtnText": {
                        "type": "string"
                      },
                      "successText": {
                        "type": "string"
                      },
                      "closeBtnText": {
                        "type": "string"
                      },
                      "displayType": {
                        "type": "string",
                        "enum": [
                          "bottombar",
                          "bottombar-hovering",
                          "toast-left",
                          "toast-right"
                        ]
                      },
                      "displayTrigger": {
                        "type": "string",
                        "enum": [
                          "element_click",
                          "element_visible",
                          "immediate",
                          "time_on_page",
                          "manual"
                        ],
                        "description": "Default \"immediate\""
                      },
                      "displayTriggerTime": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Seconds, required for \"time_on_page\""
                      },
                      "displayTriggerSelector": {
                        "type": "string",
                        "description": "Required for element_click and element_visible"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "once_a_month",
                          "once_a_quarter",
                          "once_a_year",
                          "once_a_week",
                          "once",
                          "always"
                        ],
                        "description": "How often the same user is asked. Default \"once_a_month\""
                      },
                      "dismissOn": {
                        "type": "string",
                        "enum": [
                          "cross_click",
                          "never"
                        ]
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "slackWebhookUrl": {
                        "type": "string",
                        "description": "Write-only. Never returned by read endpoints"
                      },
                      "discordWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "zapierWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "customWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "notificationEmails": {
                        "type": "string",
                        "description": "Comma-separated. Write-only"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWidgetDetail"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published NPS widget",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stats/widgets/{entityType}": {
      "get": {
        "summary": "Widget stats by entity type",
        "tags": [
          "Stats"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "tour",
                "checklist",
                "smartTip",
                "announcement",
                "changelog",
                "npsWidget",
                "roadmap"
              ]
            },
            "required": true,
            "name": "entityType",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": false,
            "name": "entityId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Widget stats",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WidgetStats"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stats/summary": {
      "get": {
        "summary": "Company-wide stats summary",
        "tags": [
          "Stats"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "startDate",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "endDate",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Stats summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatsSummary"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}": {
      "get": {
        "summary": "Get an identified user",
        "description": "Returns the user's attributes and timestamps. metadata can be null for users identified client-side without attributes.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "The user's external ID — the same value you pass to window.Produktly.identifyUser(). URL-encode it.",
              "example": "user_123"
            },
            "required": true,
            "name": "userId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "userId": "user_123",
                  "metadata": {
                    "plan": "pro",
                    "seats": 12
                  },
                  "createdAt": "2026-07-01T09:00:00.000Z",
                  "updatedAt": "2026-07-15T09:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or replace an identified user",
        "description": "Server-side equivalent of identifyUser() with replace semantics: creates the user if it doesn't exist (201), otherwise replaces its entire metadata object (200). Prefer PATCH for scheduled syncs so you don't clobber attributes set client-side.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "The user's external ID — the same value you pass to window.Produktly.identifyUser(). URL-encode it.",
              "example": "user_123"
            },
            "required": true,
            "name": "userId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {},
                    "description": "User attributes as a JSON object (nested values allowed, max 32 KB serialized). Replaces the entire stored metadata object.",
                    "example": {
                      "plan": "pro",
                      "seats": 12
                    }
                  }
                },
                "required": [
                  "metadata"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Replaced",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "userId": "user_123",
                  "metadata": {
                    "plan": "pro",
                    "seats": 12
                  },
                  "createdAt": "2026-07-01T09:00:00.000Z",
                  "updatedAt": "2026-07-15T09:00:00.000Z"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "userId": "user_123",
                  "metadata": {
                    "plan": "pro",
                    "seats": 12
                  },
                  "createdAt": "2026-07-15T09:00:00.000Z",
                  "updatedAt": "2026-07-15T09:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Merge attributes into an identified user",
        "description": "Shallow-merges the given attributes into the user's metadata (RFC 7386 style at the top level): keys overwrite, null removes a key, omitted keys are kept. Creates the user if it doesn't exist (201).",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "The user's external ID — the same value you pass to window.Produktly.identifyUser(). URL-encode it.",
              "example": "user_123"
            },
            "required": true,
            "name": "userId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {},
                    "description": "Attributes to merge (shallow, top level): keys overwrite, a key set to null is removed, omitted keys are kept, nested objects replace wholesale. Merged result max 32 KB serialized.",
                    "example": {
                      "plan": "enterprise",
                      "trialEndsAt": null
                    }
                  }
                },
                "required": [
                  "metadata"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "userId": "user_123",
                  "metadata": {
                    "plan": "enterprise",
                    "seats": 12
                  },
                  "createdAt": "2026-07-01T09:00:00.000Z",
                  "updatedAt": "2026-07-15T09:00:00.000Z"
                }
              }
            }
          },
          "201": {
            "description": "Created (the patch was merged into an empty object)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "userId": "user_123",
                  "metadata": {
                    "plan": "enterprise"
                  },
                  "createdAt": "2026-07-15T09:00:00.000Z",
                  "updatedAt": "2026-07-15T09:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete an identified user",
        "description": "Hard-deletes the identified user. Analytics events are kept (they reference the external ID as a plain string).",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "The user's external ID — the same value you pass to window.Produktly.identifyUser(). URL-encode it.",
              "example": "user_123"
            },
            "required": true,
            "name": "userId",
            "in": "path"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. No response body."
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tags": {
      "get": {
        "summary": "List tags",
        "tags": [
          "Tags"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of tags",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/product-tours": {
      "get": {
        "summary": "List product tours",
        "tags": [
          "Product Tours"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of product tours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductTourList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a product tour",
        "description": "Creates the tour as a draft. Pass active: true to publish immediately — the tour must have at least one step and targeting set, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the tour in the builder.",
        "tags": [
          "Product Tours"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "steps": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "highlight"
                              ]
                            },
                            "domQuery": {
                              "type": "string",
                              "minLength": 1,
                              "description": "CSS selector of the element to spotlight. Prefer stable data-* attributes"
                            },
                            "direction": {
                              "type": "string",
                              "enum": [
                                "auto",
                                "top",
                                "right",
                                "bottom",
                                "left"
                              ],
                              "description": "Card placement relative to the element. Default: auto"
                            },
                            "highlight": {
                              "anyOf": [
                                {
                                  "type": "boolean"
                                },
                                {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              ],
                              "description": "Spotlight cutout on/off. Default yes"
                            },
                            "allowClickEvents": {
                              "type": "boolean",
                              "description": "Let the user click the highlighted element. Default true"
                            },
                            "dismissOverlaysOnLeave": {
                              "type": "boolean",
                              "description": "Fire Escape/outside-click when leaving this step (closes dropdowns the step opened)"
                            },
                            "skipIfNotFound": {
                              "anyOf": [
                                {
                                  "type": "boolean"
                                },
                                {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              ],
                              "description": "Skip this step if the element never appears (after settings.timeout seconds). Default no (falls back to a centered modal)"
                            },
                            "expandSelectors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Extra selectors merged into the spotlight rect (e.g. portaled dropdowns)"
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type",
                            "domQuery"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "modal"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "static"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "welcome"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "toast"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "redirect"
                              ]
                            },
                            "id": {
                              "type": "string"
                            },
                            "redirectUrl": {
                              "type": "string",
                              "minLength": 1,
                              "description": "URL to navigate to. Supports {user.attr} and {currentUrl} templates. Title/content are never shown on redirect steps"
                            }
                          },
                          "required": [
                            "type",
                            "redirectUrl"
                          ],
                          "additionalProperties": false
                        }
                      ]
                    },
                    "description": "Tour steps in order. A tour with no steps never shows"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ],
                    "description": "Where the tour shows. Omit for an untargeted draft; without targeting the tour can never show"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "tourStart": {
                        "type": "string",
                        "enum": [
                          "minified",
                          "immediate-minified",
                          "immediate",
                          "manually"
                        ],
                        "description": "How the tour starts. Default \"minified\" (beacon). \"manually\" = only via Produktly.startTour()"
                      },
                      "startDelay": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Seconds before start. Default 0"
                      },
                      "trigger": {
                        "type": "string",
                        "enum": [
                          "once",
                          "always"
                        ],
                        "description": "Default \"once\""
                      },
                      "saveProgress": {
                        "type": "boolean",
                        "description": "Resume where the user left off. Default true"
                      },
                      "hideBeacon": {
                        "anyOf": [
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "string",
                            "enum": [
                              "yes",
                              "no"
                            ]
                          }
                        ],
                        "description": "Only meaningful with tourStart \"manually\". Default no"
                      },
                      "beaconPosition": {
                        "type": "string",
                        "enum": [
                          "bottom-right",
                          "bottom-left"
                        ]
                      },
                      "multiPageEnabled": {
                        "type": "boolean",
                        "description": "Continue the tour across page loads. Default true"
                      },
                      "timeout": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Seconds to wait for a step's element. Default 5"
                      },
                      "allowClosingTour": {
                        "type": "boolean",
                        "description": "Show the X / allow Escape. Default true"
                      },
                      "closeOnOutsideClick": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "themeColor": {
                        "type": "string",
                        "description": "CSS color. Overridden by an attached theme"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "nextBtnText": {
                        "type": "string"
                      },
                      "backBtnText": {
                        "type": "string"
                      },
                      "finishBtnText": {
                        "type": "string"
                      },
                      "startTourBtnText": {
                        "type": "string",
                        "description": "Beacon label. Default \"Start Product Tour\""
                      },
                      "continueTourBtnText": {
                        "type": "string",
                        "description": "Default \"Continue Tour\""
                      }
                    },
                    "additionalProperties": false
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. The tour needs at least one step and targeting set; otherwise it is saved as a draft and the response note explains why."
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created tour",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductTour"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/product-tours/{id}": {
      "get": {
        "summary": "Get a product tour",
        "tags": [
          "Product Tours"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The product tour",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductTour"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a product tour",
        "description": "Only the fields you send are changed. steps and targeting replace their stored values wholesale — fetch the tour first and send the full array back, preserving step ids. settings are merged. Live tours can be edited, but an update that would leave a live tour unpublishable (no steps or no targeting) returns 400; set active: false first to take it down.",
        "tags": [
          "Product Tours"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "steps": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "highlight"
                              ]
                            },
                            "domQuery": {
                              "type": "string",
                              "minLength": 1,
                              "description": "CSS selector of the element to spotlight. Prefer stable data-* attributes"
                            },
                            "direction": {
                              "type": "string",
                              "enum": [
                                "auto",
                                "top",
                                "right",
                                "bottom",
                                "left"
                              ],
                              "description": "Card placement relative to the element. Default: auto"
                            },
                            "highlight": {
                              "anyOf": [
                                {
                                  "type": "boolean"
                                },
                                {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              ],
                              "description": "Spotlight cutout on/off. Default yes"
                            },
                            "allowClickEvents": {
                              "type": "boolean",
                              "description": "Let the user click the highlighted element. Default true"
                            },
                            "dismissOverlaysOnLeave": {
                              "type": "boolean",
                              "description": "Fire Escape/outside-click when leaving this step (closes dropdowns the step opened)"
                            },
                            "skipIfNotFound": {
                              "anyOf": [
                                {
                                  "type": "boolean"
                                },
                                {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              ],
                              "description": "Skip this step if the element never appears (after settings.timeout seconds). Default no (falls back to a centered modal)"
                            },
                            "expandSelectors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Extra selectors merged into the spotlight rect (e.g. portaled dropdowns)"
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type",
                            "domQuery"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "modal"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "static"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "welcome"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "toast"
                              ]
                            },
                            "id": {
                              "type": "string",
                              "description": "Server-generated UUID — omit on create, preserve on update (analytics key on it)"
                            },
                            "title": {
                              "type": "string",
                              "description": "Plain text (HTML is escaped). Supports {{user.attr}} templates"
                            },
                            "content": {
                              "type": "string",
                              "description": "HTML body (sanitized at render; iframes allowed). Supports {{user.attr | fallback}} templates"
                            },
                            "width": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card width px. Widget default: 492 welcome, 432 others"
                            },
                            "height": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Card height px; content scrolls beyond it"
                            },
                            "nextBtnText": {
                              "type": "string"
                            },
                            "backBtnText": {
                              "type": "string"
                            },
                            "finishBtnText": {
                              "type": "string"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "none",
                                "open_url",
                                "start_tour"
                              ],
                              "description": "Optional secondary button. It never advances the tour"
                            },
                            "actionText": {
                              "type": "string"
                            },
                            "actionUrl": {
                              "type": "string",
                              "description": "Required when action=open_url"
                            },
                            "openActionUrlInNewTab": {
                              "type": "boolean"
                            },
                            "closeTourOnAction": {
                              "type": "boolean"
                            },
                            "actionTourId": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "description": "Required when action=start_tour"
                            },
                            "actionListeners": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "click",
                                      "hover",
                                      "focus",
                                      "user_input",
                                      "element_visible"
                                    ]
                                  },
                                  "domQuery": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "CSS selector the listener attaches to"
                                  },
                                  "delay": {
                                    "type": "number",
                                    "minimum": 0,
                                    "description": "Seconds to wait after the event before advancing. Defaults: 1 for user_input, 0.25 otherwise"
                                  },
                                  "hideButtons": {
                                    "anyOf": [
                                      {
                                        "type": "boolean"
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "yes",
                                          "no"
                                        ]
                                      }
                                    ],
                                    "description": "Hide Back/Next while waiting for the event. Default yes"
                                  }
                                },
                                "required": [
                                  "type",
                                  "domQuery"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 1,
                              "description": "Auto-advance when the user interacts with an element (max 1)"
                            },
                            "showDarkBackground": {
                              "type": "boolean",
                              "description": "Backdrop. Widget default: true for modal/welcome, false for toast"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "redirect"
                              ]
                            },
                            "id": {
                              "type": "string"
                            },
                            "redirectUrl": {
                              "type": "string",
                              "minLength": 1,
                              "description": "URL to navigate to. Supports {user.attr} and {currentUrl} templates. Title/content are never shown on redirect steps"
                            }
                          },
                          "required": [
                            "type",
                            "redirectUrl"
                          ],
                          "additionalProperties": false
                        }
                      ]
                    },
                    "description": "Replaces ALL steps. Fetch the tour first and send back the full array, preserving step ids"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ],
                    "description": "Replaces the whole targeting config"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "tourStart": {
                        "type": "string",
                        "enum": [
                          "minified",
                          "immediate-minified",
                          "immediate",
                          "manually"
                        ],
                        "description": "How the tour starts. Default \"minified\" (beacon). \"manually\" = only via Produktly.startTour()"
                      },
                      "startDelay": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Seconds before start. Default 0"
                      },
                      "trigger": {
                        "type": "string",
                        "enum": [
                          "once",
                          "always"
                        ],
                        "description": "Default \"once\""
                      },
                      "saveProgress": {
                        "type": "boolean",
                        "description": "Resume where the user left off. Default true"
                      },
                      "hideBeacon": {
                        "anyOf": [
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "string",
                            "enum": [
                              "yes",
                              "no"
                            ]
                          }
                        ],
                        "description": "Only meaningful with tourStart \"manually\". Default no"
                      },
                      "beaconPosition": {
                        "type": "string",
                        "enum": [
                          "bottom-right",
                          "bottom-left"
                        ]
                      },
                      "multiPageEnabled": {
                        "type": "boolean",
                        "description": "Continue the tour across page loads. Default true"
                      },
                      "timeout": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Seconds to wait for a step's element. Default 5"
                      },
                      "allowClosingTour": {
                        "type": "boolean",
                        "description": "Show the X / allow Escape. Default true"
                      },
                      "closeOnOutsideClick": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "themeColor": {
                        "type": "string",
                        "description": "CSS color. Overridden by an attached theme"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "nextBtnText": {
                        "type": "string"
                      },
                      "backBtnText": {
                        "type": "string"
                      },
                      "finishBtnText": {
                        "type": "string"
                      },
                      "startTourBtnText": {
                        "type": "string",
                        "description": "Beacon label. Default \"Start Product Tour\""
                      },
                      "continueTourBtnText": {
                        "type": "string",
                        "description": "Default \"Continue Tour\""
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings; only provided keys change"
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Set live or back to draft. Publishing requires the widget to be publishable (see the create schema); unpublishing always works."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductTour"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published tour",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/checklists": {
      "get": {
        "summary": "List checklists",
        "tags": [
          "Checklists"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of checklists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChecklistList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a checklist",
        "description": "Creates the checklist as a draft. Pass active: true to publish immediately — the checklist must have at least one item and targeting set, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the checklist in the builder.",
        "tags": [
          "Checklists"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Shown as the checklist panel header"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Server-generated UUID — omit on create, preserve on update (completion state keys on it)"
                        },
                        "title": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Supports {{user.attr}} templates"
                        },
                        "content": {
                          "type": "string",
                          "description": "HTML body shown under the title (sanitized at render)"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "start-tour",
                            "open-url",
                            "custom"
                          ],
                          "description": "Click action: start a tour, open a URL, or \"custom\" (no click action; completes via events)"
                        },
                        "tourId": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Required when type=start-tour"
                        },
                        "redirectToUrl": {
                          "type": "string",
                          "description": "Required when type=open-url. Supports {user.attr} and {currentUrl} templates"
                        },
                        "completionType": {
                          "type": "string",
                          "enum": [
                            "page-event",
                            "manual-click",
                            "tour-complete"
                          ],
                          "description": "What marks the item complete. page-event: a DOM event on the customer site; manual-click: the user ticks it; tour-complete: a tour finishes"
                        },
                        "eventType": {
                          "type": "string",
                          "enum": [
                            "click",
                            "hover",
                            "element-visible"
                          ],
                          "description": "With completionType=page-event. Default \"click\". element-visible = present in DOM (checked every 2s)"
                        },
                        "pageEventElementSelector": {
                          "type": "string",
                          "description": "Required when completionType=page-event: CSS selector the event must hit"
                        },
                        "tourToCompleteId": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Required when completionType=tour-complete (auto-filled from tourId for start-tour items)"
                        },
                        "allowManualCompletion": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            }
                          ],
                          "description": "Also allow ticking manually on top of page-event/tour-complete. Default no"
                        },
                        "allowToRetake": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            }
                          ],
                          "description": "Completed items can still fire their click action. Default no"
                        },
                        "allowUncheck": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            }
                          ],
                          "description": "Completed items can be unchecked. Default no"
                        }
                      },
                      "required": [
                        "title",
                        "type",
                        "completionType"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "displayMode": {
                        "type": "string",
                        "enum": [
                          "floating",
                          "embedded"
                        ],
                        "description": "Default \"floating\""
                      },
                      "containerSelector": {
                        "type": "string",
                        "description": "Required when displayMode=embedded: CSS selector of the element to render into"
                      },
                      "checklistStart": {
                        "type": "string",
                        "enum": [
                          "minified",
                          "immediate",
                          "manually"
                        ],
                        "description": "Default \"minified\". \"manually\" = only via Produktly.startChecklist()"
                      },
                      "hideBeacon": {
                        "anyOf": [
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "string",
                            "enum": [
                              "yes",
                              "no"
                            ]
                          }
                        ]
                      },
                      "checklistPosition": {
                        "type": "string",
                        "enum": [
                          "bottom-right",
                          "bottom-left",
                          "top-right",
                          "top-left"
                        ]
                      },
                      "beaconPosition": {
                        "type": "string",
                        "enum": [
                          "bottom-right",
                          "bottom-left"
                        ]
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "completedColor": {
                        "type": "string",
                        "description": "Default \"#61d345\""
                      },
                      "showChecklistBtnText": {
                        "type": "string"
                      },
                      "continueChecklistBtnText": {
                        "type": "string"
                      },
                      "showChecklistAfterFinishBtnText": {
                        "type": "string"
                      },
                      "percentageCompletedText": {
                        "type": "string"
                      },
                      "checklistCompletedText": {
                        "type": "string"
                      },
                      "finishChecklistBtnText": {
                        "type": "string"
                      },
                      "markAsCompletedText": {
                        "type": "string"
                      },
                      "markAsCompletedConfirmText": {
                        "type": "string"
                      },
                      "markAsCompletedCancelText": {
                        "type": "string"
                      },
                      "markAsUncompletedText": {
                        "type": "string"
                      },
                      "markAsUncompletedConfirmText": {
                        "type": "string"
                      },
                      "markAsUncompletedCancelText": {
                        "type": "string"
                      }
                    },
                    "additionalProperties": false
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. The checklist needs at least one item and targeting set; otherwise it is saved as a draft and the response note explains why."
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created checklist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Checklist"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/checklists/{id}": {
      "get": {
        "summary": "Get a checklist",
        "tags": [
          "Checklists"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The checklist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Checklist"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a checklist",
        "description": "Only the fields you send are changed. items and targeting replace their stored values wholesale — fetch the checklist first and send the full array back, preserving item ids (completion state is keyed on them). settings are merged. Live checklists can be edited, but an update that would leave one unpublishable (no items or no targeting) returns 400; set active: false first to take it down.",
        "tags": [
          "Checklists"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Server-generated UUID — omit on create, preserve on update (completion state keys on it)"
                        },
                        "title": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Supports {{user.attr}} templates"
                        },
                        "content": {
                          "type": "string",
                          "description": "HTML body shown under the title (sanitized at render)"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "start-tour",
                            "open-url",
                            "custom"
                          ],
                          "description": "Click action: start a tour, open a URL, or \"custom\" (no click action; completes via events)"
                        },
                        "tourId": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Required when type=start-tour"
                        },
                        "redirectToUrl": {
                          "type": "string",
                          "description": "Required when type=open-url. Supports {user.attr} and {currentUrl} templates"
                        },
                        "completionType": {
                          "type": "string",
                          "enum": [
                            "page-event",
                            "manual-click",
                            "tour-complete"
                          ],
                          "description": "What marks the item complete. page-event: a DOM event on the customer site; manual-click: the user ticks it; tour-complete: a tour finishes"
                        },
                        "eventType": {
                          "type": "string",
                          "enum": [
                            "click",
                            "hover",
                            "element-visible"
                          ],
                          "description": "With completionType=page-event. Default \"click\". element-visible = present in DOM (checked every 2s)"
                        },
                        "pageEventElementSelector": {
                          "type": "string",
                          "description": "Required when completionType=page-event: CSS selector the event must hit"
                        },
                        "tourToCompleteId": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Required when completionType=tour-complete (auto-filled from tourId for start-tour items)"
                        },
                        "allowManualCompletion": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            }
                          ],
                          "description": "Also allow ticking manually on top of page-event/tour-complete. Default no"
                        },
                        "allowToRetake": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            }
                          ],
                          "description": "Completed items can still fire their click action. Default no"
                        },
                        "allowUncheck": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            }
                          ],
                          "description": "Completed items can be unchecked. Default no"
                        }
                      },
                      "required": [
                        "title",
                        "type",
                        "completionType"
                      ],
                      "additionalProperties": false
                    },
                    "description": "Replaces ALL items. Fetch first and send back the full array, preserving item ids"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "displayMode": {
                        "type": "string",
                        "enum": [
                          "floating",
                          "embedded"
                        ],
                        "description": "Default \"floating\""
                      },
                      "containerSelector": {
                        "type": "string",
                        "description": "Required when displayMode=embedded: CSS selector of the element to render into"
                      },
                      "checklistStart": {
                        "type": "string",
                        "enum": [
                          "minified",
                          "immediate",
                          "manually"
                        ],
                        "description": "Default \"minified\". \"manually\" = only via Produktly.startChecklist()"
                      },
                      "hideBeacon": {
                        "anyOf": [
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "string",
                            "enum": [
                              "yes",
                              "no"
                            ]
                          }
                        ]
                      },
                      "checklistPosition": {
                        "type": "string",
                        "enum": [
                          "bottom-right",
                          "bottom-left",
                          "top-right",
                          "top-left"
                        ]
                      },
                      "beaconPosition": {
                        "type": "string",
                        "enum": [
                          "bottom-right",
                          "bottom-left"
                        ]
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "completedColor": {
                        "type": "string",
                        "description": "Default \"#61d345\""
                      },
                      "showChecklistBtnText": {
                        "type": "string"
                      },
                      "continueChecklistBtnText": {
                        "type": "string"
                      },
                      "showChecklistAfterFinishBtnText": {
                        "type": "string"
                      },
                      "percentageCompletedText": {
                        "type": "string"
                      },
                      "checklistCompletedText": {
                        "type": "string"
                      },
                      "finishChecklistBtnText": {
                        "type": "string"
                      },
                      "markAsCompletedText": {
                        "type": "string"
                      },
                      "markAsCompletedConfirmText": {
                        "type": "string"
                      },
                      "markAsCompletedCancelText": {
                        "type": "string"
                      },
                      "markAsUncompletedText": {
                        "type": "string"
                      },
                      "markAsUncompletedConfirmText": {
                        "type": "string"
                      },
                      "markAsUncompletedCancelText": {
                        "type": "string"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings"
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Set live or back to draft. Publishing requires the widget to be publishable (see the create schema); unpublishing always works."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Checklist"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published checklist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/smart-tips": {
      "get": {
        "summary": "List smart tips",
        "tags": [
          "Smart Tips"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of smart tips",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmartTipList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a smart tip",
        "description": "Creates the tip as a draft. Pass active: true to publish immediately — the tip must have settings.cssSelector and targeting set, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the tip in the builder.",
        "tags": [
          "Smart Tips"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Internal name"
                  },
                  "title": {
                    "type": "string",
                    "description": "Card title (plain text)"
                  },
                  "content": {
                    "type": "string",
                    "description": "Card body as HTML"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "cssSelector": {
                        "type": "string",
                        "minLength": 1,
                        "description": "CSS selector of the element the tip anchors to. Required — without it nothing renders"
                      },
                      "displayOn": {
                        "type": "string",
                        "enum": [
                          "click",
                          "hover",
                          "focus",
                          "beacon_click",
                          "beacon_hover"
                        ],
                        "description": "What opens the tip. Default \"click\""
                      },
                      "hideWhen": {
                        "type": "string",
                        "enum": [
                          "click",
                          "mouse_leaves"
                        ],
                        "description": "Only honored for hover triggers. Default \"click\""
                      },
                      "displayBeacon": {
                        "type": "boolean",
                        "description": "Show the beacon dot. Default true"
                      },
                      "beaconStyle": {
                        "type": "string",
                        "enum": [
                          "pulsating_point",
                          "question_mark",
                          "info_icon"
                        ]
                      },
                      "offsetX": {
                        "type": "number",
                        "description": "Beacon X offset in px. Must be a number — the widget ignores numeric strings"
                      },
                      "offsetY": {
                        "type": "number",
                        "description": "Beacon Y offset in px. Must be a number — the widget ignores numeric strings"
                      },
                      "orientElement": {
                        "type": "string",
                        "enum": [
                          "element",
                          "beacon"
                        ],
                        "description": "Default \"element\""
                      },
                      "cardOrientation": {
                        "type": "string",
                        "enum": [
                          "auto",
                          "top",
                          "bottom",
                          "left",
                          "right"
                        ]
                      },
                      "hideWhenOffPage": {
                        "type": "boolean"
                      },
                      "width": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Card width px. Default 356"
                      },
                      "height": {
                        "type": "integer",
                        "exclusiveMinimum": 0
                      },
                      "overrideZIndex": {
                        "type": "integer"
                      },
                      "action": {
                        "type": "string",
                        "enum": [
                          "none",
                          "open_url",
                          "start_tour"
                        ]
                      },
                      "actionText": {
                        "type": "string"
                      },
                      "actionUrl": {
                        "type": "string",
                        "description": "Required when action=open_url"
                      },
                      "openActionUrlInNewTab": {
                        "type": "boolean"
                      },
                      "tourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when action=start_tour"
                      },
                      "secondaryAction": {
                        "type": "string",
                        "enum": [
                          "none",
                          "open_url",
                          "start_tour"
                        ]
                      },
                      "secondaryActionText": {
                        "type": "string"
                      },
                      "secondaryActionUrl": {
                        "type": "string"
                      },
                      "secondaryOpenActionUrlInNewTab": {
                        "type": "boolean"
                      },
                      "secondaryTourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0
                      },
                      "actionPosition": {
                        "type": "string",
                        "enum": [
                          "left",
                          "center",
                          "right"
                        ]
                      },
                      "themeColor": {
                        "type": "string",
                        "description": "Overridden by an attached theme"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "once",
                          "always",
                          "custom"
                        ],
                        "description": "How often it shows. Default \"once\""
                      },
                      "displayTimes": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when display=\"custom\""
                      }
                    },
                    "required": [
                      "cssSelector"
                    ],
                    "additionalProperties": false
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ],
                    "description": "Where the tip shows. Without targeting it can never show"
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. Needs settings.cssSelector and targeting; otherwise saved as a draft and the response note explains why"
                  }
                },
                "required": [
                  "name",
                  "settings"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created smart tip",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmartTip"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/smart-tips/{id}": {
      "get": {
        "summary": "Get a smart tip",
        "tags": [
          "Smart Tips"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The smart tip",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmartTip"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a smart tip",
        "description": "Only the fields you send are changed. settings are merged over stored settings; targeting replaces wholesale. Live tips can be edited, but an update that would leave one unpublishable (no cssSelector or no targeting) returns 400; set active: false first to take it down.",
        "tags": [
          "Smart Tips"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "title": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "cssSelector": {
                        "type": "string",
                        "minLength": 1,
                        "description": "CSS selector of the element the tip anchors to"
                      },
                      "displayOn": {
                        "type": "string",
                        "enum": [
                          "click",
                          "hover",
                          "focus",
                          "beacon_click",
                          "beacon_hover"
                        ],
                        "description": "What opens the tip. Default \"click\""
                      },
                      "hideWhen": {
                        "type": "string",
                        "enum": [
                          "click",
                          "mouse_leaves"
                        ],
                        "description": "Only honored for hover triggers. Default \"click\""
                      },
                      "displayBeacon": {
                        "type": "boolean",
                        "description": "Show the beacon dot. Default true"
                      },
                      "beaconStyle": {
                        "type": "string",
                        "enum": [
                          "pulsating_point",
                          "question_mark",
                          "info_icon"
                        ]
                      },
                      "offsetX": {
                        "type": "number",
                        "description": "Beacon X offset in px. Must be a number — the widget ignores numeric strings"
                      },
                      "offsetY": {
                        "type": "number",
                        "description": "Beacon Y offset in px. Must be a number — the widget ignores numeric strings"
                      },
                      "orientElement": {
                        "type": "string",
                        "enum": [
                          "element",
                          "beacon"
                        ],
                        "description": "Default \"element\""
                      },
                      "cardOrientation": {
                        "type": "string",
                        "enum": [
                          "auto",
                          "top",
                          "bottom",
                          "left",
                          "right"
                        ]
                      },
                      "hideWhenOffPage": {
                        "type": "boolean"
                      },
                      "width": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Card width px. Default 356"
                      },
                      "height": {
                        "type": "integer",
                        "exclusiveMinimum": 0
                      },
                      "overrideZIndex": {
                        "type": "integer"
                      },
                      "action": {
                        "type": "string",
                        "enum": [
                          "none",
                          "open_url",
                          "start_tour"
                        ]
                      },
                      "actionText": {
                        "type": "string"
                      },
                      "actionUrl": {
                        "type": "string",
                        "description": "Required when action=open_url"
                      },
                      "openActionUrlInNewTab": {
                        "type": "boolean"
                      },
                      "tourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when action=start_tour"
                      },
                      "secondaryAction": {
                        "type": "string",
                        "enum": [
                          "none",
                          "open_url",
                          "start_tour"
                        ]
                      },
                      "secondaryActionText": {
                        "type": "string"
                      },
                      "secondaryActionUrl": {
                        "type": "string"
                      },
                      "secondaryOpenActionUrlInNewTab": {
                        "type": "boolean"
                      },
                      "secondaryTourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0
                      },
                      "actionPosition": {
                        "type": "string",
                        "enum": [
                          "left",
                          "center",
                          "right"
                        ]
                      },
                      "themeColor": {
                        "type": "string",
                        "description": "Overridden by an attached theme"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "once",
                          "always",
                          "custom"
                        ],
                        "description": "How often it shows. Default \"once\""
                      },
                      "displayTimes": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when display=\"custom\""
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ],
                    "description": "Replaces the whole targeting config"
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Set live or back to draft"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmartTip"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published smart tip",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/announcements": {
      "get": {
        "summary": "List announcements",
        "tags": [
          "Announcements"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of announcements",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnnouncementList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create an announcement",
        "description": "Creates the announcement as a draft. Pass active: true to publish immediately — the announcement must have a title and targeting set, plus content for popup and toast types, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the announcement in the builder.",
        "tags": [
          "Announcements"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "title": {
                    "type": "string",
                    "description": "Headline. The only text shown on topbar types"
                  },
                  "content": {
                    "type": "string",
                    "description": "HTML body. Rendered for popup and toast only"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "topbar",
                          "topbar-hovering",
                          "popup",
                          "toast"
                        ],
                        "description": "Display style. Default \"topbar\". content is only rendered for popup and toast"
                      },
                      "isSticky": {
                        "type": "boolean",
                        "description": "Topbar only. Default true"
                      },
                      "pushContentDown": {
                        "type": "boolean",
                        "description": "Topbar only. Sticky placement needs isSticky and this"
                      },
                      "toastLocation": {
                        "type": "string",
                        "enum": [
                          "bottomleft",
                          "bottomright",
                          "topleft",
                          "topright"
                        ],
                        "description": "Toast only. Default \"bottomleft\""
                      },
                      "width": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Popup/toast only. Defaults 500 / 320"
                      },
                      "height": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Popup/toast only"
                      },
                      "showCloseButton": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "showActionButton": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "actionText": {
                        "type": "string",
                        "description": "Default \"Learn more\""
                      },
                      "actionType": {
                        "type": "string",
                        "enum": [
                          "url",
                          "tour"
                        ],
                        "description": "Default \"url\""
                      },
                      "actionLink": {
                        "type": "string"
                      },
                      "actionTourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0
                      },
                      "actionOpenInNewTab": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "showSecondaryActionButton": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "secondaryActionText": {
                        "type": "string"
                      },
                      "secondaryActionType": {
                        "type": "string",
                        "enum": [
                          "url",
                          "tour"
                        ],
                        "description": "Default \"url\""
                      },
                      "secondaryActionLink": {
                        "type": "string"
                      },
                      "secondaryActionTourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when secondaryActionType is tour"
                      },
                      "secondaryActionOpenInNewTab": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "once",
                          "always",
                          "custom"
                        ],
                        "description": "Default \"once\""
                      },
                      "displayTimes": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when display=\"custom\""
                      }
                    },
                    "additionalProperties": false
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. Needs a title and targeting, plus content for popup and toast"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created announcement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Announcement"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/announcements/{id}": {
      "get": {
        "summary": "Get an announcement",
        "tags": [
          "Announcements"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The announcement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Announcement"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update an announcement",
        "description": "Only the fields you send are changed. settings are merged over stored settings; targeting replaces wholesale. Live announcements can be edited, but an update that would leave one unpublishable (no title, no targeting, or missing content for popup/toast) returns 400; set active: false first to take it down.",
        "tags": [
          "Announcements"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "title": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "topbar",
                          "topbar-hovering",
                          "popup",
                          "toast"
                        ],
                        "description": "Display style. Default \"topbar\". content is only rendered for popup and toast"
                      },
                      "isSticky": {
                        "type": "boolean",
                        "description": "Topbar only. Default true"
                      },
                      "pushContentDown": {
                        "type": "boolean",
                        "description": "Topbar only. Sticky placement needs isSticky and this"
                      },
                      "toastLocation": {
                        "type": "string",
                        "enum": [
                          "bottomleft",
                          "bottomright",
                          "topleft",
                          "topright"
                        ],
                        "description": "Toast only. Default \"bottomleft\""
                      },
                      "width": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Popup/toast only. Defaults 500 / 320"
                      },
                      "height": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Popup/toast only"
                      },
                      "showCloseButton": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "showActionButton": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "actionText": {
                        "type": "string",
                        "description": "Default \"Learn more\""
                      },
                      "actionType": {
                        "type": "string",
                        "enum": [
                          "url",
                          "tour"
                        ],
                        "description": "Default \"url\""
                      },
                      "actionLink": {
                        "type": "string"
                      },
                      "actionTourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0
                      },
                      "actionOpenInNewTab": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "showSecondaryActionButton": {
                        "type": "boolean",
                        "description": "Default false"
                      },
                      "secondaryActionText": {
                        "type": "string"
                      },
                      "secondaryActionType": {
                        "type": "string",
                        "enum": [
                          "url",
                          "tour"
                        ],
                        "description": "Default \"url\""
                      },
                      "secondaryActionLink": {
                        "type": "string"
                      },
                      "secondaryActionTourId": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when secondaryActionType is tour"
                      },
                      "secondaryActionOpenInNewTab": {
                        "type": "boolean",
                        "description": "Default true"
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "once",
                          "always",
                          "custom"
                        ],
                        "description": "Default \"once\""
                      },
                      "displayTimes": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "description": "Required when display=\"custom\""
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Announcement"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published announcement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/micro-surveys": {
      "get": {
        "summary": "List micro surveys",
        "tags": [
          "Micro Surveys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of micro surveys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MicroSurveyList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a micro survey",
        "description": "Creates the survey as a draft. Pass active: true to publish immediately — the survey must have at least one question and targeting set, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the survey in the builder.",
        "tags": [
          "Micro Surveys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "questions": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "question": {
                              "type": "string",
                              "minLength": 1,
                              "description": "The question text. Response payloads key on this"
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "emoji",
                                "thumbs",
                                "rating",
                                "text",
                                "multi-choice"
                              ],
                              "description": "Default \"emoji\". thumbs (👍/👎), rating (fixed 1-5) and text take no options"
                            },
                            "options": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  "emoji": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                },
                                "required": [
                                  "name",
                                  "emoji"
                                ],
                                "additionalProperties": false
                              },
                              "description": "Only for type \"emoji\""
                            },
                            "multiChoiceOptions": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1
                              },
                              "description": "Only for type \"multi-choice\""
                            }
                          },
                          "required": [
                            "question"
                          ],
                          "additionalProperties": false
                        },
                        "minItems": 1,
                        "description": "Questions in order. Shown one at a time"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "always",
                          "until_answered"
                        ],
                        "description": "Default \"always\""
                      },
                      "displayTrigger": {
                        "type": "string",
                        "enum": [
                          "click",
                          "hover",
                          "focus",
                          "element_visible",
                          "immediate",
                          "time_delay",
                          "manual"
                        ],
                        "description": "Default \"click\". \"manual\" = only via Produktly.openMicroSurvey()"
                      },
                      "cssSelector": {
                        "type": "string",
                        "description": "Required for click, hover, focus and element_visible triggers"
                      },
                      "displayDelay": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Seconds, with displayTrigger \"time_delay\". Default 5"
                      },
                      "autoClose": {
                        "type": "boolean"
                      },
                      "autoCloseAfter": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Seconds. Default 20"
                      },
                      "position": {
                        "type": "string",
                        "enum": [
                          "element",
                          "bottom-center",
                          "bottom-left",
                          "bottom-right",
                          "top-center",
                          "top-left",
                          "top-right"
                        ]
                      },
                      "positionCssSelector": {
                        "type": "string",
                        "description": "Falls back to cssSelector"
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "onCompleteActions": {
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "start_tour"
                                  ]
                                },
                                "tourId": {
                                  "type": "integer",
                                  "exclusiveMinimum": 0
                                }
                              },
                              "required": [
                                "type",
                                "tourId"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "open_micro_survey"
                                  ]
                                },
                                "microSurveyId": {
                                  "type": "integer",
                                  "exclusiveMinimum": 0
                                }
                              },
                              "required": [
                                "type",
                                "microSurveyId"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "open_url"
                                  ]
                                },
                                "url": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "openInNewTab": {
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "type",
                                "url"
                              ],
                              "additionalProperties": false
                            }
                          ]
                        },
                        "maxItems": 1,
                        "description": "What happens after the last question (max 1)"
                      },
                      "slackWebhookUrl": {
                        "type": "string",
                        "description": "Write-only. Never returned by read endpoints"
                      },
                      "discordWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "zapierWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "customWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "notificationEmails": {
                        "type": "string",
                        "description": "Comma-separated. Write-only"
                      }
                    },
                    "required": [
                      "questions"
                    ],
                    "additionalProperties": false
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Publish immediately. Needs at least one question and targeting"
                  }
                },
                "required": [
                  "name",
                  "settings"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created micro survey",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MicroSurvey"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/micro-surveys/{id}": {
      "get": {
        "summary": "Get a micro survey",
        "tags": [
          "Micro Surveys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The micro survey",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MicroSurvey"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a micro survey",
        "description": "Only the fields you send are changed. settings are merged over stored settings; targeting replaces wholesale. Live surveys can be edited, but an update that would leave one unpublishable (no questions or no targeting) returns 400; set active: false first to take it down.",
        "tags": [
          "Micro Surveys"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "questions": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "question": {
                              "type": "string",
                              "minLength": 1,
                              "description": "The question text. Response payloads key on this"
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "emoji",
                                "thumbs",
                                "rating",
                                "text",
                                "multi-choice"
                              ],
                              "description": "Default \"emoji\". thumbs (👍/👎), rating (fixed 1-5) and text take no options"
                            },
                            "options": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  "emoji": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                },
                                "required": [
                                  "name",
                                  "emoji"
                                ],
                                "additionalProperties": false
                              },
                              "description": "Only for type \"emoji\""
                            },
                            "multiChoiceOptions": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1
                              },
                              "description": "Only for type \"multi-choice\""
                            }
                          },
                          "required": [
                            "question"
                          ],
                          "additionalProperties": false
                        },
                        "minItems": 1,
                        "description": "Questions in order. Shown one at a time"
                      },
                      "display": {
                        "type": "string",
                        "enum": [
                          "always",
                          "until_answered"
                        ],
                        "description": "Default \"always\""
                      },
                      "displayTrigger": {
                        "type": "string",
                        "enum": [
                          "click",
                          "hover",
                          "focus",
                          "element_visible",
                          "immediate",
                          "time_delay",
                          "manual"
                        ],
                        "description": "Default \"click\". \"manual\" = only via Produktly.openMicroSurvey()"
                      },
                      "cssSelector": {
                        "type": "string",
                        "description": "Required for click, hover, focus and element_visible triggers"
                      },
                      "displayDelay": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Seconds, with displayTrigger \"time_delay\". Default 5"
                      },
                      "autoClose": {
                        "type": "boolean"
                      },
                      "autoCloseAfter": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Seconds. Default 20"
                      },
                      "position": {
                        "type": "string",
                        "enum": [
                          "element",
                          "bottom-center",
                          "bottom-left",
                          "bottom-right",
                          "top-center",
                          "top-left",
                          "top-right"
                        ]
                      },
                      "positionCssSelector": {
                        "type": "string",
                        "description": "Falls back to cssSelector"
                      },
                      "themeColor": {
                        "type": "string"
                      },
                      "textColor": {
                        "type": "string"
                      },
                      "onCompleteActions": {
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "start_tour"
                                  ]
                                },
                                "tourId": {
                                  "type": "integer",
                                  "exclusiveMinimum": 0
                                }
                              },
                              "required": [
                                "type",
                                "tourId"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "open_micro_survey"
                                  ]
                                },
                                "microSurveyId": {
                                  "type": "integer",
                                  "exclusiveMinimum": 0
                                }
                              },
                              "required": [
                                "type",
                                "microSurveyId"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "open_url"
                                  ]
                                },
                                "url": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "openInNewTab": {
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "type",
                                "url"
                              ],
                              "additionalProperties": false
                            }
                          ]
                        },
                        "maxItems": 1,
                        "description": "What happens after the last question (max 1)"
                      },
                      "slackWebhookUrl": {
                        "type": "string",
                        "description": "Write-only. Never returned by read endpoints"
                      },
                      "discordWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "zapierWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "customWebhookUrl": {
                        "type": "string",
                        "description": "Write-only"
                      },
                      "notificationEmails": {
                        "type": "string",
                        "description": "Comma-separated. Write-only"
                      }
                    },
                    "additionalProperties": false,
                    "description": "Merged over existing settings"
                  },
                  "targeting": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "showOnAllPages": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          }
                        },
                        "required": [
                          "showOnAllPages"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "rules": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "url",
                                        "current_time",
                                        "day_of_week",
                                        "location",
                                        "language",
                                        "produktly_user_created_at",
                                        "device_type",
                                        "screen_width",
                                        "screen_height"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "pattern": "^custom::::.+"
                                    }
                                  ]
                                },
                                "comparisonOperator": {
                                  "type": "string",
                                  "enum": [
                                    "equals",
                                    "not_equal",
                                    "contains",
                                    "no_contains",
                                    "starts_with",
                                    "ends_with",
                                    "one_of",
                                    "not_one_of",
                                    "greater",
                                    "greater_eq",
                                    "less",
                                    "less_eq",
                                    "exists",
                                    "not_exists",
                                    "time_ago",
                                    "within_last"
                                  ]
                                },
                                "value": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "number"
                                          }
                                        ]
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "value": {
                                          "type": "integer",
                                          "exclusiveMinimum": 0
                                        },
                                        "unit": {
                                          "type": "string",
                                          "enum": [
                                            "minutes",
                                            "hours",
                                            "days",
                                            "weeks",
                                            "months",
                                            "years"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "value",
                                        "unit"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "comparisonOperator"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 1
                          },
                          "logicalOperator": {
                            "type": "string",
                            "enum": [
                              "AND",
                              "OR",
                              "and",
                              "or"
                            ],
                            "description": "How multiple rules combine. Default \"AND\"."
                          }
                        },
                        "required": [
                          "rules"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "userSegmentIds": {
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "exclusiveMinimum": 0
                            },
                            "minItems": 1
                          }
                        },
                        "required": [
                          "userSegmentIds"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "themeId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "folderId": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "exclusiveMinimum": 0
                  },
                  "active": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MicroSurvey"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "widget_is_live — this API key cannot edit a published micro survey",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}