{
  "openapi": "3.0.0",
  "paths": {
    "/": {
      "get": {
        "operationId": "AppController_getHello",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "summary": "Liveness greeting endpoint.",
        "tags": [
          "App"
        ]
      }
    },
    "/health/redis": {
      "get": {
        "operationId": "HealthController_redisHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Redis memory headroom — poll this from an uptime monitor.\n\nA full Redis makes BullMQ reject every write (lock renewal, job completion,\ndequeuing), which silently halts sending and loses in-flight jobs. Returns\n`level: ok | warning | critical | unknown`; alert on anything but `ok`.\nSamples live rather than serving a cached reading so a probe always sees\ncurrent state, falling back to the last scheduled sample on error.",
        "tags": [
          "Health"
        ]
      }
    },
    "/health": {
      "get": {
        "operationId": "HealthController_check",
        "parameters": [],
        "responses": {
          "200": {
            "description": "The Health Check is successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "info": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "status"
                        ],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "error": {
                      "type": "object",
                      "example": {},
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "status"
                        ],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "details": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "status"
                        ],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The Health Check is not successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "error"
                    },
                    "info": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "status"
                        ],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "error": {
                      "type": "object",
                      "example": {
                        "redis": {
                          "status": "down",
                          "message": "Could not connect"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "status"
                        ],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "details": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        },
                        "redis": {
                          "status": "down",
                          "message": "Could not connect"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "status"
                        ],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Primary readiness probe. Checks DB, cache, and worker heartbeats for\nconfigured groups when Redis is enabled.\n\nOnly components listed in `HEALTH_REQUIRED_COMPONENTS` (default:\n`database`) can fail the probe. Anything else that is down is reported as\n`degraded` with HTTP 200, because an instance that can still read Postgres\ncan still serve — see health-requirements.ts for why this matters.\n\nThe response keeps Terminus's `{ status, info, error, details }` shape and\nadds `degraded: string[]` naming the down-but-tolerated components.",
        "tags": [
          "Health"
        ]
      }
    },
    "/health/queues": {
      "get": {
        "operationId": "HealthController_queueHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Health"
        ]
      }
    },
    "/health/apis": {
      "get": {
        "operationId": "HealthController_apiHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Health"
        ]
      }
    },
    "/health/circuits": {
      "get": {
        "operationId": "HealthController_circuitHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Circuit-breaker states for external dependencies (e.g. the shared `goldrush`\ncircuit). `degraded` when any circuit is open or half-open probing, so ops\ncan spot a tripped upstream without reading logs. Cheap: an in-memory read.",
        "tags": [
          "Health"
        ]
      }
    },
    "/health/mcp": {
      "get": {
        "operationId": "HealthController_mcpHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Health"
        ]
      }
    },
    "/health/worker": {
      "get": {
        "operationId": "HealthController_workerReadiness",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Worker readiness detail: heartbeat freshness per required group (skipped if Redis off).",
        "tags": [
          "Health"
        ]
      }
    },
    "/intelligence/insights/generate": {
      "post": {
        "operationId": "InsightsController_generate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateInsightDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate insight (internal trigger)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/insights/latest": {
      "get": {
        "operationId": "InsightsController_latest",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get latest insight",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/insights": {
      "get": {
        "operationId": "InsightsController_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "example": 20,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List insights",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/insights/{insightId}": {
      "get": {
        "operationId": "InsightsController_get",
        "parameters": [
          {
            "name": "insightId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get single insight",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/insights/{insightId}/dismiss": {
      "post": {
        "operationId": "InsightsController_dismiss",
        "parameters": [
          {
            "name": "insightId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dismiss insight",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/insights/{insightId}/act": {
      "post": {
        "operationId": "InsightsController_act",
        "parameters": [
          {
            "name": "insightId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Act on insight (fork recommended play)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/run": {
      "post": {
        "operationId": "IntelligenceQueryController_run",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute a user query (async)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/run": {
      "post": {
        "operationId": "IntelligenceQueryController_runGoldrush",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute a cache-aware GoldRush wallet query and persist the run",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/tools": {
      "get": {
        "operationId": "IntelligenceQueryController_listGoldrushMcpTools",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available GoldRush MCP tools exposed by the official server",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/resources": {
      "get": {
        "operationId": "IntelligenceQueryController_listGoldrushMcpResources",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available GoldRush MCP resources exposed by the official server",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/catalog": {
      "get": {
        "operationId": "IntelligenceQueryController_getGoldrushMcpCatalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch the live GoldRush MCP catalog, including tools and resources",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/run": {
      "post": {
        "operationId": "IntelligenceQueryController_runGoldrushMcpTool",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute an official GoldRush MCP tool through the backend",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/resources/read": {
      "post": {
        "operationId": "IntelligenceQueryController_readGoldrushMcpResource",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Read a live GoldRush MCP resource through the backend",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/pool": {
      "get": {
        "operationId": "IntelligenceQueryController_getGoldrushMcpPool",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Inspect the pooled GoldRush MCP runtime health and capacity",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/pool/warm": {
      "post": {
        "operationId": "IntelligenceQueryController_warmGoldrushMcpPool",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Warm the GoldRush MCP pool to the configured minimum size",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/pool/reset": {
      "post": {
        "operationId": "IntelligenceQueryController_resetGoldrushMcpPool",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Recycle all GoldRush MCP pooled sessions and warm the pool again",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/plan": {
      "post": {
        "operationId": "IntelligenceQueryController_planGoldrushMcpQuery",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resolve prompt, protocol, and saved settings into a GoldRush MCP execution plan",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/query": {
      "post": {
        "operationId": "IntelligenceQueryController_executeGoldrushMcpQuery",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dynamically route any prompt through the live GoldRush MCP tool catalog and return the answer",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/query/stream": {
      "post": {
        "operationId": "IntelligenceQueryController_streamGoldrushMcpQueryPost",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stream a dynamic GoldRush MCP query with live agent progress updates over POST (SSE)",
        "tags": [
          "Intelligence"
        ]
      },
      "get": {
        "operationId": "IntelligenceQueryController_streamGoldrushMcpQuery",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stream a dynamic GoldRush MCP query with live agent progress updates (SSE)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/conversations": {
      "get": {
        "operationId": "IntelligenceQueryController_listGoldrushMcpConversations",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List persisted GoldRush MCP conversations",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/goldrush/mcp/conversations/{conversationId}": {
      "get": {
        "operationId": "IntelligenceQueryController_getGoldrushMcpConversation",
        "parameters": [
          {
            "name": "conversationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a persisted GoldRush MCP conversation",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/starters": {
      "get": {
        "operationId": "IntelligenceQueryController_starterQueries",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List starter saved queries for the Intelligence SQL editor",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/suggestions": {
      "post": {
        "operationId": "IntelligenceQueryController_suggestQueries",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Suggest protocol-aware and sector-aware Intelligence queries using AI",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/protocols": {
      "get": {
        "operationId": "IntelligenceQueryController_listProtocols",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sector",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List saved protocol registry entries for AI query suggestions",
        "tags": [
          "Intelligence"
        ]
      },
      "post": {
        "operationId": "IntelligenceQueryController_upsertProtocol",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create or update a protocol registry entry for AI query suggestions",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/suggestions/{logId}/track": {
      "post": {
        "operationId": "IntelligenceQueryController_trackSuggestionUsage",
        "parameters": [
          {
            "name": "logId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Track usage analytics for an AI query suggestion",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/suggestions/analytics": {
      "get": {
        "operationId": "IntelligenceQueryController_getSuggestionAnalytics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get AI query suggestion analytics for the active organization",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/generate-sql": {
      "post": {
        "operationId": "IntelligenceQueryController_generateSql",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate safe SQL from a natural-language prompt using Groq + LangChain",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/credits": {
      "get": {
        "operationId": "IntelligenceQueryController_getCreditMeter",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "GoldRush credit meter for the active org: used / limit / remaining / status (ok|warn|exceeded) for the current month",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/enrichment/status": {
      "get": {
        "operationId": "IntelligenceQueryController_getEnrichmentStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enrichment progress: enriched-wallet count, latest lastEnrichedAt, and queue depth (idle = drained)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/enrichment/protocol": {
      "post": {
        "operationId": "IntelligenceQueryController_enqueueProtocolEnrichment",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enrich a protocol from settings: discover each contract's holders via GoldRush and enqueue per-wallet enrichment (+ contacts)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/enrichment/wallets/enqueue-and-wait": {
      "post": {
        "operationId": "IntelligenceQueryController_enqueueWalletEnrichmentAndWait",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enrich a single wallet and briefly wait for the result in one call (for a frontend \"enrich this wallet\" action)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/enrichment/wallets/enqueue": {
      "post": {
        "operationId": "IntelligenceQueryController_enqueueWalletEnrichment",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enqueue or run a GoldRush enrichment job for a single wallet",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/enrichment/contacts/enqueue": {
      "post": {
        "operationId": "IntelligenceQueryController_enqueueContactEnrichment",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enqueue enrichment jobs for recent contacts with wallet addresses",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/enrichment/wallets/{walletAddress}": {
      "get": {
        "operationId": "IntelligenceQueryController_getWalletEnrichment",
        "parameters": [
          {
            "name": "walletAddress",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get the latest materialized wallet enrichment metrics",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/{queryId}/status": {
      "get": {
        "operationId": "IntelligenceQueryController_status",
        "parameters": [
          {
            "name": "queryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get query execution status",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/{queryId}/results": {
      "get": {
        "operationId": "IntelligenceQueryController_results",
        "parameters": [
          {
            "name": "queryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get paginated query results",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/{queryId}/summary": {
      "get": {
        "operationId": "IntelligenceQueryController_summary",
        "parameters": [
          {
            "name": "queryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get query summary",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/validate": {
      "post": {
        "operationId": "IntelligenceQueryController_validate",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Validate query syntax before running",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/cache": {
      "get": {
        "operationId": "IntelligenceQueryController_listCaches",
        "parameters": [
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "resourceType",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "subjectAddress",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List persisted GoldRush cache entries for the org",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/cache/{cacheId}": {
      "get": {
        "operationId": "IntelligenceQueryController_getCache",
        "parameters": [
          {
            "name": "cacheId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a persisted GoldRush cache entry",
        "tags": [
          "Intelligence"
        ]
      },
      "delete": {
        "operationId": "IntelligenceQueryController_deleteCache",
        "parameters": [
          {
            "name": "cacheId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invalidate a persisted GoldRush cache entry",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/history": {
      "get": {
        "operationId": "IntelligenceQueryController_history",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List recent query history for current user",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/{queryId}/save": {
      "post": {
        "operationId": "IntelligenceQueryController_save",
        "parameters": [
          {
            "name": "queryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save query as a named report",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/{queryId}/report-data": {
      "get": {
        "operationId": "IntelligenceQueryController_queryReportData",
        "parameters": [
          {
            "name": "queryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Chart-ready report payload for a stored query (typed columns, auto-suggested line/bar/pie charts, summary stats, table)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/{queryId}/export.csv": {
      "get": {
        "operationId": "IntelligenceQueryController_queryExportCsv",
        "parameters": [
          {
            "name": "queryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download stored query results as CSV (full, uncapped rows)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/segments/from-query": {
      "post": {
        "operationId": "IntelligenceQueryController_segmentFromQuery",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an audience segment from query results",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/campaign/from-query": {
      "post": {
        "operationId": "IntelligenceQueryController_campaignFromQuery",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a campaign from query results",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/assistant": {
      "post": {
        "operationId": "IntelligenceMetaController_askAssistant",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ask the multi-source intelligence assistant (in-process, tool-using chat)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/assistant/stream": {
      "post": {
        "operationId": "IntelligenceMetaController_askAssistantStream",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stream the intelligence assistant over SSE (live tokens + tool/proposed events)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/tools": {
      "get": {
        "operationId": "IntelligenceMetaController_listTools",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the intelligence agent tool catalog (function-calling schemas)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/tools/run": {
      "post": {
        "operationId": "IntelligenceMetaController_runTool",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute one intelligence tool (read tools run; action tools need confirm:true)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/schema": {
      "get": {
        "operationId": "IntelligenceMetaController_schema",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get schema for query editor autocomplete",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/recommendations": {
      "get": {
        "operationId": "IntelligenceMetaController_recommendations",
        "parameters": [
          {
            "name": "narrate",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Retention recommendations: cohorts from contact_360 mapped to Plays + email templates",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/metrics": {
      "get": {
        "operationId": "IntelligenceMetaController_metrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Intelligence metrics",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments": {
      "get": {
        "operationId": "IntelligenceSegmentsController_list",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List segments",
        "tags": [
          "Intelligence"
        ]
      },
      "post": {
        "operationId": "IntelligenceSegmentsController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create segment (manual)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/metrics": {
      "get": {
        "operationId": "IntelligenceSegmentsController_metrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Segments metrics",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/import-from-query": {
      "post": {
        "operationId": "IntelligenceSegmentsController_importFromQuery",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Import segment from query results",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/preview": {
      "post": {
        "operationId": "IntelligenceSegmentsController_preview",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewSegmentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preview an un-persisted rule set: live count + up to 10 sample wallets (nothing saved)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/generate-rules": {
      "post": {
        "operationId": "IntelligenceSegmentsController_generateRules",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateRulesDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Convert a natural-language prompt into structured segment rules",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/{segmentId}": {
      "get": {
        "operationId": "IntelligenceSegmentsController_get",
        "parameters": [
          {
            "name": "segmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get segment detail",
        "tags": [
          "Intelligence"
        ]
      },
      "put": {
        "operationId": "IntelligenceSegmentsController_update",
        "parameters": [
          {
            "name": "segmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update segment",
        "tags": [
          "Intelligence"
        ]
      },
      "delete": {
        "operationId": "IntelligenceSegmentsController_del",
        "parameters": [
          {
            "name": "segmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete segment",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/{segmentId}/refresh": {
      "post": {
        "operationId": "IntelligenceSegmentsController_refresh",
        "parameters": [
          {
            "name": "segmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Refresh segment stats",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/{segmentId}/profiles": {
      "get": {
        "operationId": "IntelligenceSegmentsController_profiles",
        "parameters": [
          {
            "name": "segmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List profiles in segment",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/segments/{segmentId}/use": {
      "post": {
        "operationId": "IntelligenceSegmentsController_use",
        "parameters": [
          {
            "name": "segmentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark segment used",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/reports": {
      "get": {
        "operationId": "IntelligenceReportsController_list",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List reports",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/reports/metrics": {
      "get": {
        "operationId": "IntelligenceReportsController_metrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reports metrics",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/reports/summary": {
      "get": {
        "operationId": "IntelligenceReportsController_summary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reports summary",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/reports/filters": {
      "get": {
        "operationId": "IntelligenceReportsController_filters",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reports filter options",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/reports/{reportId}": {
      "get": {
        "operationId": "IntelligenceReportsController_get",
        "parameters": [
          {
            "name": "reportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get report detail",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/reports/{reportId}/refresh": {
      "post": {
        "operationId": "IntelligenceReportsController_refresh",
        "parameters": [
          {
            "name": "reportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Refresh report (no-op MVP)",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/pipelines": {
      "get": {
        "operationId": "IntelligencePipelinesController_list",
        "parameters": [
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List GoldRush-backed intelligence pipelines",
        "tags": [
          "Intelligence"
        ]
      },
      "post": {
        "operationId": "IntelligencePipelinesController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an intelligence pipeline with GoldRush Pipeline API sync",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/pipelines/{pipelineId}": {
      "get": {
        "operationId": "IntelligencePipelinesController_get",
        "parameters": [
          {
            "name": "pipelineId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an intelligence pipeline",
        "tags": [
          "Intelligence"
        ]
      },
      "put": {
        "operationId": "IntelligencePipelinesController_update",
        "parameters": [
          {
            "name": "pipelineId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update an intelligence pipeline and resync it",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/pipelines/{pipelineId}/sync": {
      "post": {
        "operationId": "IntelligencePipelinesController_sync",
        "parameters": [
          {
            "name": "pipelineId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Force a sync of a local pipeline to GoldRush",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/templates": {
      "get": {
        "operationId": "IntelligenceQueryTemplatesController_list",
        "parameters": [
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List safe parameterized intelligence query templates",
        "tags": [
          "Intelligence"
        ]
      },
      "post": {
        "operationId": "IntelligenceQueryTemplatesController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a safe parameterized intelligence query template",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/templates/{templateId}": {
      "get": {
        "operationId": "IntelligenceQueryTemplatesController_get",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a safe parameterized intelligence query template",
        "tags": [
          "Intelligence"
        ]
      },
      "put": {
        "operationId": "IntelligenceQueryTemplatesController_update",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a safe parameterized intelligence query template",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/intelligence/query/templates/{templateId}/run": {
      "post": {
        "operationId": "IntelligenceQueryTemplatesController_run",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Run a safe parameterized intelligence query template and optionally materialize it",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/automations/builder/contracts/resolve": {
      "get": {
        "operationId": "ContractAbiController_resolve",
        "parameters": [
          {
            "name": "chain",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resolve a contract ABI and its watchable events",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/contracts/parse-abi": {
      "post": {
        "operationId": "ContractAbiController_parseAbi",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Parse a pasted ABI into watchable events",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/templates": {
      "get": {
        "operationId": "AutomationTemplatesController_list",
        "parameters": [
          {
            "name": "tier",
            "required": false,
            "in": "query",
            "schema": {
              "example": "starter|advanced",
              "type": "string"
            }
          },
          {
            "name": "protocolType",
            "required": false,
            "in": "query",
            "schema": {
              "example": "defi|nft|gaming|dao",
              "type": "string"
            }
          },
          {
            "name": "showAdvanced",
            "required": false,
            "in": "query",
            "schema": {
              "example": "true|false",
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "visibility",
            "required": false,
            "in": "query",
            "schema": {
              "example": "all|public|private",
              "type": "string",
              "enum": [
                "all",
                "public",
                "private"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List automation templates (Plays)",
        "tags": [
          "Automations"
        ]
      },
      "post": {
        "operationId": "AutomationTemplatesController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertAutomationTemplateDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create automation template",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/templates/{templateId}": {
      "get": {
        "operationId": "AutomationTemplatesController_get",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get single automation template",
        "tags": [
          "Automations"
        ]
      },
      "put": {
        "operationId": "AutomationTemplatesController_update",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertAutomationTemplateDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update automation template",
        "tags": [
          "Automations"
        ]
      },
      "delete": {
        "operationId": "AutomationTemplatesController_remove",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete automation template",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/templates/{templateId}/apply": {
      "post": {
        "operationId": "AutomationTemplatesController_apply",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyTemplateDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Apply template (fork into draft automation)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/triggers": {
      "get": {
        "operationId": "AutomationsController_builderTriggers",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List trigger types for builder",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/onchain/catalog": {
      "get": {
        "operationId": "AutomationsController_builderOnchainCatalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List multichain on-chain event definitions supported by the automation builder",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/onchain/contract-events": {
      "get": {
        "operationId": "AutomationsController_builderContractEvents",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Events a specific contract emits (for the trigger's Event dropdown)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/triggers/{triggerType}": {
      "get": {
        "operationId": "AutomationsController_builderTriggerSchema",
        "parameters": [
          {
            "name": "triggerType",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get trigger config schema",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/triggers/available": {
      "get": {
        "operationId": "AutomationsController_triggersAvailable",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available triggers (alias)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/actions": {
      "get": {
        "operationId": "AutomationsController_builderActions",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List action node types for builder",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/actions/{actionType}": {
      "get": {
        "operationId": "AutomationsController_builderActionSchema",
        "parameters": [
          {
            "name": "actionType",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get action config schema",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/email-templates": {
      "get": {
        "operationId": "AutomationsController_builderEmailTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List backend-driven email templates for automation nodes",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations": {
      "get": {
        "operationId": "AutomationsController_list",
        "parameters": [
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tab",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List automations",
        "tags": [
          "Automations"
        ]
      },
      "post": {
        "operationId": "AutomationsController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create automation (starts as draft)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/metrics": {
      "get": {
        "operationId": "AutomationsController_metrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automations metrics",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/counts": {
      "get": {
        "operationId": "AutomationsController_counts",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automation tab counters",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/search": {
      "get": {
        "operationId": "AutomationsController_search",
        "parameters": [
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Search automations",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/builder/project-contracts": {
      "get": {
        "operationId": "AutomationsController_listProjectContracts",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Project settings' GoldRush-supported contracts/chains for the builder trigger picker",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}": {
      "get": {
        "operationId": "AutomationsController_get",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get single automation",
        "tags": [
          "Automations"
        ]
      },
      "put": {
        "operationId": "AutomationsController_update",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update automation",
        "tags": [
          "Automations"
        ]
      },
      "delete": {
        "operationId": "AutomationsController_delete",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete automation",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/status": {
      "put": {
        "operationId": "AutomationsController_updateStatus",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Quick toggle status",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/publish": {
      "post": {
        "operationId": "AutomationsController_publish",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish/activate a draft",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/duplicate": {
      "post": {
        "operationId": "AutomationsController_duplicate",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Duplicate automation",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/last-edited": {
      "get": {
        "operationId": "AutomationsController_lastEdited",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get last edited timestamp (legacy)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/builder": {
      "get": {
        "operationId": "AutomationsController_getBuilder",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Load automation for builder editing",
        "tags": [
          "Automations"
        ]
      },
      "put": {
        "operationId": "AutomationsController_saveBuilder",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save automation builder flow",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/builder/draft": {
      "put": {
        "operationId": "AutomationsController_saveBuilderDraft",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Auto-save draft builder flow",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/builder/validate": {
      "post": {
        "operationId": "AutomationsController_validateBuilder",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Validate automation builder flow",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/builder/discard": {
      "post": {
        "operationId": "AutomationsController_discardBuilder",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Discard builder changes back to the last saved graph",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/builder/reset": {
      "post": {
        "operationId": "AutomationsController_resetBuilder",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Persistently reset the automation builder back to a blank draft",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/tag-test-send": {
      "post": {
        "operationId": "AutomationsController_tagTestSend",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Click-to-tag test send for an automation email node",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/send-test": {
      "post": {
        "operationId": "AutomationsController_sendTest",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send a test of an automation email node (tag-aware)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/preview": {
      "post": {
        "operationId": "AutomationsController_preview",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preview audience match for trigger",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats/preview": {
      "get": {
        "operationId": "AutomationsController_statsPreview",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Projected stats preview (MVP)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/performance": {
      "get": {
        "operationId": "AutomationsController_performance",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automation performance (alias to stats)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats": {
      "get": {
        "operationId": "AutomationsController_stats",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automation stats overview",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/flow-analytics": {
      "get": {
        "operationId": "AutomationsController_flowAnalytics",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Per-node funnel (reached / completed / dropped) for the flow",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats/time-series": {
      "get": {
        "operationId": "AutomationsController_timeSeries",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automation time series stats",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats/paths": {
      "get": {
        "operationId": "AutomationsController_paths",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automation path performance (MVP)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats/entries": {
      "get": {
        "operationId": "AutomationsController_entries",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Paginated entries (user journeys)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats/entries/{entryId}": {
      "get": {
        "operationId": "AutomationsController_entry",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "entryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Single entry details",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/{automationId}/stats/revenue": {
      "get": {
        "operationId": "AutomationsController_revenue",
        "parameters": [
          {
            "name": "automationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Revenue attribution (MVP stub)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/channels/dispatch": {
      "post": {
        "operationId": "ChannelsController_dispatch",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Channel router fanout entry point",
        "tags": [
          "Channels"
        ]
      }
    },
    "/v2/channels/dispatch": {
      "post": {
        "operationId": "ChannelsV2Controller_dispatch",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Channel dispatch (server-to-server using sk_*)",
        "tags": [
          "Channels (Protocol)"
        ]
      }
    },
    "/automations/runtime/goldrush/status": {
      "get": {
        "operationId": "AutomationRuntimeController_getGoldrushStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Inspect GoldRush automation stream status and configured sources",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/segment-entered": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestSegmentEntered",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest a segment_entered automation trigger event",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/list-joined": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestListJoined",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest a list_joined automation trigger event (alias of segment_entered)",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/form-submitted": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestFormSubmitted",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest a form_submitted automation trigger event",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/onchain-event": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestOnchainEvent",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest an on-chain automation trigger event",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/goldrush-event": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestGoldrushEvent",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest a GoldRush-decoded multichain automation trigger event",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/goldrush-event/queue": {
      "post": {
        "operationId": "AutomationRuntimeController_queueGoldrushEvent",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Queue a GoldRush-decoded automation trigger event for durable processing",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/goldrush-events/batch": {
      "post": {
        "operationId": "AutomationRuntimeController_queueGoldrushEventsBatch",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Queue a batch of GoldRush-decoded automation trigger events",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/email-opened": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestEmailOpened",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest an email_opened automation trigger event",
        "tags": [
          "Automations"
        ]
      }
    },
    "/automations/runtime/triggers/health-threshold": {
      "post": {
        "operationId": "AutomationRuntimeController_ingestHealthThreshold",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest a health_threshold automation trigger event",
        "tags": [
          "Automations"
        ]
      }
    },
    "/v2/automations/runtime/triggers/segment-entered": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_ingestSegmentEntered",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Ingest a segment_entered automation trigger event (server-to-server using sk_*)",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/v2/automations/runtime/triggers/onchain-event": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_ingestOnchainEvent",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Ingest an on-chain automation trigger event (server-to-server using sk_*)",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/v2/automations/runtime/triggers/goldrush-event": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_ingestGoldrushEvent",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Ingest a GoldRush-decoded multichain automation trigger event (server-to-server using sk_*)",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/v2/automations/runtime/triggers/goldrush-event/queue": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_queueGoldrushEvent",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Queue a GoldRush-decoded automation trigger event for durable server-to-server processing",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/v2/automations/runtime/triggers/goldrush-events/batch": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_queueGoldrushEventsBatch",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Queue a batch of GoldRush-decoded automation trigger events for durable server-to-server processing",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/v2/automations/runtime/triggers/email-opened": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_ingestEmailOpened",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Ingest an email_opened automation trigger event (server-to-server using sk_*)",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/v2/automations/runtime/triggers/health-threshold": {
      "post": {
        "operationId": "AutomationRuntimeV2Controller_ingestHealthThreshold",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Ingest a health_threshold automation trigger event (server-to-server using sk_*)",
        "tags": [
          "Automations (Protocol)"
        ]
      }
    },
    "/webhooks/alchemy": {
      "post": {
        "operationId": "AlchemyWebhookController_receive",
        "parameters": [
          {
            "name": "x-alchemy-signature",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Alchemy Notify webhook — on-chain event ingestion",
        "tags": [
          "automations (alchemy webhook)"
        ]
      }
    },
    "/email/reputation": {
      "get": {
        "operationId": "EmailController_getReputation",
        "parameters": [
          {
            "name": "windowDays",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sender reputation for the active org (bounce/complaint/open rates + status)",
        "tags": [
          "Email"
        ]
      }
    },
    "/email/send": {
      "post": {
        "operationId": "EmailController_sendEmail",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Email queued successfully."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Queue an email for sending",
        "tags": [
          "Email"
        ]
      }
    },
    "/webhooks/azure/email-events": {
      "post": {
        "operationId": "AzureEmailEventsController_handle",
        "parameters": [
          {
            "name": "key",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "aeg-event-type",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Azure Event Grid: ACS email delivery/engagement reports",
        "tags": [
          "webhooks"
        ]
      }
    },
    "/webhook/ses": {
      "post": {
        "operationId": "SesEmailEventsController_handle",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "AWS SNS: SES email delivery/engagement events (public)",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/webhook/sendgrid": {
      "post": {
        "operationId": "SendGridEmailEventsController_handle",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "SendGrid Event Webhook: bounce/complaint/unsubscribe events (public, ECDSA-signed)",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/email/sending-policies": {
      "get": {
        "operationId": "SendingPolicyController_listPolicies",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List domain sending policies + live usage (org-scoped; platform admin sees all)",
        "tags": [
          "Email Sending Policies"
        ]
      }
    },
    "/email/sending-policies/{domain}/sending-status": {
      "get": {
        "operationId": "SendingPolicyController_getSendingStatus",
        "parameters": [
          {
            "name": "domain",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "One domain: effective limits, warm-up day, live usage, 7-day reputation, tier-request readiness",
        "tags": [
          "Email Sending Policies"
        ]
      }
    },
    "/email/sending-policies/{domain}": {
      "put": {
        "operationId": "SendingPolicyController_updatePolicy",
        "parameters": [
          {
            "name": "domain",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSendingPolicyDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a domain sending policy (tier fields platform-admin only; pause/cap/notes for org admins)",
        "tags": [
          "Email Sending Policies"
        ]
      }
    },
    "/email/sending-policies/{domain}/start-warmup": {
      "post": {
        "operationId": "SendingPolicyController_startWarmup",
        "parameters": [
          {
            "name": "domain",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Idempotently start the warm-up curve for a domain (auto-invoked on verification)",
        "tags": [
          "Email Sending Policies"
        ]
      }
    },
    "/email/unsubscribe/{token}": {
      "post": {
        "operationId": "EmailUnsubscribeController_oneClick",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "RFC 8058 one-click unsubscribe (public, idempotent; List-Unsubscribe-Post target)",
        "tags": [
          "Email"
        ]
      },
      "get": {
        "operationId": "EmailUnsubscribeController_confirmPage",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Unsubscribe via browser (public; performs the unsubscribe and returns a minimal confirmation page)",
        "tags": [
          "Email"
        ]
      }
    },
    "/admin/email/providers/health": {
      "get": {
        "operationId": "EmailProviderHealthController_getProvidersHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Multi-provider email health (ACS/SendGrid/SES side-by-side): configured, active role, 24h/7d bounce+complaint reputation (platform admin)",
        "tags": [
          "Admin Email Monitoring"
        ]
      }
    },
    "/domain": {
      "post": {
        "operationId": "DomainController_createDomain",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domain registered successfully."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Register a new domain (Owned or Managed)",
        "tags": [
          "Domain"
        ]
      },
      "get": {
        "operationId": "DomainController_listDomains",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List all domains for the current user",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/azure/status": {
      "get": {
        "operationId": "DomainController_azureStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Diagnostic: ARM management-plane config + live probe of the Email service (read-only)",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/check": {
      "get": {
        "operationId": "DomainController_checkAvailability",
        "parameters": [
          {
            "name": "domain",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "OWNED",
                "MANAGED"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check if a domain is already registered",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}": {
      "get": {
        "operationId": "DomainController_getDomain",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get domain details",
        "tags": [
          "Domain"
        ]
      },
      "delete": {
        "operationId": "DomainController_deleteDomain",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a domain identity",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/status": {
      "get": {
        "operationId": "DomainController_checkStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check domain verification status",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/provision": {
      "post": {
        "operationId": "DomainController_provisionDomain",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Authenticate the domain in the configured send providers (SendGrid/SES/ACS) and return all their DNS records",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/sendgrid/authenticate": {
      "post": {
        "operationId": "DomainController_authenticateSendGrid",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Register the domain with SendGrid and return the CNAME records to publish",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/sendgrid/validate": {
      "post": {
        "operationId": "DomainController_validateSendGrid",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ask SendGrid to re-check DNS and report verification status",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/recheck": {
      "post": {
        "operationId": "DomainController_recheckStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Retry domain verification and return the updated status",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/sync": {
      "post": {
        "operationId": "DomainController_syncDomain",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Re-sync a verified domain: ensure default sender identity + Communication Service link (idempotent)",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/verify": {
      "post": {
        "operationId": "DomainController_verifyDomain",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait",
            "required": false,
            "in": "query",
            "description": "Wait for verification to complete (best-effort)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Trigger domain verification in Azure",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/dns": {
      "get": {
        "operationId": "DomainController_getDnsRecords",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "required": false,
            "in": "query",
            "description": "Preview a specific provider's checklist: 'ses' shows the SES-only view (DKIM CNAMEs + MAIL FROM + DMARC) regardless of the saved purpose. Omit to show the DNS for the domain's saved purpose (marketing → SES, transactional → ACS). The response's `provider`/`purpose` reflect the saved choice.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get DNS records for domain verification",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/purpose": {
      "put": {
        "operationId": "DomainController_setDomainPurpose",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDomainPurposeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set a domain's purpose: 'transactional' (Azure ACS) or 'marketing' (AWS SES). Drives send routing and which DNS records the checklist shows.",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/dns/auto": {
      "post": {
        "operationId": "DomainController_addDnsAuto",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutoDnsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automatically add DNS records via provider API",
        "tags": [
          "Domain"
        ]
      }
    },
    "/domain/{id}/senders": {
      "post": {
        "operationId": "DomainController_addSender",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSenderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a sender username to a verified domain",
        "tags": [
          "Domain"
        ]
      }
    },
    "/sender-identities": {
      "get": {
        "operationId": "SenderIdentityController_listSenderIdentities",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List sender identities",
        "tags": [
          "Sender Verification"
        ]
      },
      "post": {
        "operationId": "SenderIdentityController_addSenderIdentity",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSenderIdentityDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add sender identity",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/sender-identities/{id}": {
      "delete": {
        "operationId": "SenderIdentityController_deleteSenderIdentity",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete sender identity",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/sender-identities/{id}/recheck": {
      "post": {
        "operationId": "SenderIdentityController_checkSenderIdentity",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Recheck sender identity verification status",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/sender-identities/{id}/dns": {
      "get": {
        "operationId": "SenderIdentityController_getSenderIdentityDns",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get DNS records for sender identity",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/sender-identities/{id}/dns/auto": {
      "post": {
        "operationId": "SenderIdentityController_addDnsRecords",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutoDnsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automatically add DNS records for sender identity",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/sender-identities/default": {
      "put": {
        "operationId": "SenderIdentityController_setDefaultSender",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDefaultSenderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set default sender identity",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/sender-identities/domains/authentication": {
      "get": {
        "operationId": "SenderIdentityController_getDomainAuthentication",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get domain authentication overview",
        "tags": [
          "Sender Verification"
        ]
      }
    },
    "/organization/list": {
      "get": {
        "operationId": "OrganizationController_listOrganizations",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List user organizations",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/create": {
      "post": {
        "operationId": "OrganizationController_createOrganization",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create organization",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization": {
      "get": {
        "operationId": "OrganizationController_getOrganization",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get current organization details",
        "tags": [
          "Organization"
        ]
      },
      "put": {
        "operationId": "OrganizationController_updateOrganization",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOrganizationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update organization details",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/project-settings": {
      "get": {
        "operationId": "OrganizationController_getProjectSettings",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get project settings used across billing, query, and messaging",
        "tags": [
          "Organization"
        ]
      },
      "put": {
        "operationId": "OrganizationController_updateProjectSettings",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProjectSettingsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update project settings used across billing, query, and messaging",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/project-settings/supported-chains": {
      "get": {
        "operationId": "OrganizationController_getSupportedChains",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List GoldRush-supported chains (with foundational/streaming capability flags) for project-settings pickers",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/settings/smart-sending": {
      "get": {
        "operationId": "OrganizationController_getSmartSendingSettings",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get org-wide Smart Sending settings (suppression window + default-on flag)",
        "tags": [
          "Organization"
        ]
      },
      "put": {
        "operationId": "OrganizationController_updateSmartSendingSettings",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSmartSendingSettingsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update org-wide Smart Sending settings (windowHours 1-168, enabledByDefault)",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/set-active": {
      "post": {
        "operationId": "OrganizationController_setActiveOrganization",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set active organization for current session",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/subdomain/validate": {
      "post": {
        "operationId": "OrganizationController_validateSubdomain",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateSubdomainDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Validate subdomain availability",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/landing-pages": {
      "get": {
        "operationId": "OrganizationController_getLandingPages",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available landing page templates",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/domains": {
      "get": {
        "operationId": "OrganizationController_getAppDomain",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get org verified app domain (in-app preview chrome)",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding": {
      "get": {
        "operationId": "OrganizationController_getBranding",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get organization branding",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding/email-builder": {
      "get": {
        "operationId": "OrganizationController_getEmailBuilderBranding",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get email builder brand settings",
        "tags": [
          "Organization"
        ]
      },
      "put": {
        "operationId": "OrganizationController_updateEmailBuilderBranding",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEmailBuilderBrandingDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update email builder brand settings",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding/logo/primary": {
      "post": {
        "operationId": "OrganizationController_uploadPrimaryLogo",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload primary logo",
        "tags": [
          "Organization"
        ]
      },
      "delete": {
        "operationId": "OrganizationController_deletePrimaryLogo",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete primary logo",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding/logo/dark": {
      "post": {
        "operationId": "OrganizationController_uploadDarkLogo",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload dark logo",
        "tags": [
          "Organization"
        ]
      },
      "delete": {
        "operationId": "OrganizationController_deleteDarkLogo",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete dark logo",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding/logo/favicon": {
      "post": {
        "operationId": "OrganizationController_uploadFavicon",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload favicon",
        "tags": [
          "Organization"
        ]
      },
      "delete": {
        "operationId": "OrganizationController_deleteFavicon",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete favicon",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding/colors": {
      "put": {
        "operationId": "OrganizationController_updateColors",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateColorsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update brand colors",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organization/branding/colors/reset": {
      "post": {
        "operationId": "OrganizationController_resetColors",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reset brand colors",
        "tags": [
          "Organization"
        ]
      }
    },
    "/organizations/{organizationId}/members": {
      "get": {
        "operationId": "OrganizationMemberController_listMembers",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number for pagination",
            "schema": {
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "example": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search term for name or email",
            "schema": {
              "example": "john",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of members returned successfully."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - User is not a member of the organization."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List organization members",
        "tags": [
          "Organization Members"
        ]
      }
    },
    "/organizations/{organizationId}/members/{userId}": {
      "patch": {
        "operationId": "OrganizationMemberController_updateMember",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          },
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the member to update",
            "schema": {
              "example": "user_987654321",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMemberDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Member updated successfully."
          },
          "400": {
            "description": "Bad Request - Invalid data or preventing last owner downgrade."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - Insufficient permissions."
          },
          "404": {
            "description": "Member not found."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update member role or status",
        "tags": [
          "Organization Members"
        ]
      },
      "delete": {
        "operationId": "OrganizationMemberController_removeMember",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          },
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the member to remove",
            "schema": {
              "example": "user_987654321",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Member removed successfully."
          },
          "400": {
            "description": "Bad Request - Cannot remove last owner."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - Insufficient permissions."
          },
          "404": {
            "description": "Member not found."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove member",
        "tags": [
          "Organization Members"
        ]
      }
    },
    "/organizations/{organizationId}/invites": {
      "post": {
        "operationId": "OrganizationMemberController_inviteMember",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteMemberDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Invitation sent successfully."
          },
          "400": {
            "description": "Bad Request - User already a member or invite pending."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - Insufficient permissions."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invite a user",
        "tags": [
          "Organization Members"
        ]
      },
      "get": {
        "operationId": "OrganizationMemberController_listInvites",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of pending invites returned successfully."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - Insufficient permissions."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List pending invites",
        "tags": [
          "Organization Members"
        ]
      }
    },
    "/organizations/{organizationId}/invites/{inviteId}": {
      "delete": {
        "operationId": "OrganizationMemberController_cancelInvite",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          },
          {
            "name": "inviteId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the invite to cancel",
            "schema": {
              "example": "invite_123456789",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invitation cancelled."
          },
          "400": {
            "description": "Bad Request - Only pending invites can be cancelled."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - Insufficient permissions."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel a pending invite",
        "tags": [
          "Organization Members"
        ]
      }
    },
    "/organizations/{organizationId}/invites/{inviteId}/resend": {
      "post": {
        "operationId": "OrganizationMemberController_resendInvite",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the organization",
            "schema": {
              "example": "org_123456789",
              "type": "string"
            }
          },
          {
            "name": "inviteId",
            "required": true,
            "in": "path",
            "description": "The unique identifier of the invite to resend",
            "schema": {
              "example": "invite_123456789",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invitation resent successfully."
          },
          "400": {
            "description": "Bad Request - Only pending invites can be resent."
          },
          "401": {
            "description": "Unauthorized."
          },
          "403": {
            "description": "Forbidden - Insufficient permissions."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resend a pending invite email",
        "tags": [
          "Organization Members"
        ]
      }
    },
    "/invites/{token}/accept": {
      "post": {
        "operationId": "OrganizationInviteController_acceptInvite",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "description": "The invitation token",
            "schema": {
              "example": "a1b2c3d4e5f6...",
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Invitation accepted successfully."
          },
          "400": {
            "description": "Bad Request - Invalid or expired token."
          },
          "401": {
            "description": "Unauthorized."
          },
          "404": {
            "description": "Invitation not found."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Accept invitation",
        "tags": [
          "Invites"
        ]
      }
    },
    "/notifications": {
      "get": {
        "operationId": "NotificationController_list",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List user notifications",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/notifications/{id}/read": {
      "put": {
        "operationId": "NotificationController_markRead",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark notification as read",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/notifications/read-all": {
      "put": {
        "operationId": "NotificationController_markAllRead",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark all notifications as read",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/auth/sign-up/email": {
      "post": {
        "operationId": "AuthController_signUp",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignUpDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User created successfully"
          }
        },
        "summary": "Sign up with email",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/verify-email": {
      "get": {
        "operationId": "AuthController_verifyEmail",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "query",
            "description": "Verification token",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Email verified successfully"
          }
        },
        "summary": "Verify email address",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/sign-in/email": {
      "post": {
        "operationId": "AuthController_signIn",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignInDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User signed in successfully"
          }
        },
        "summary": "Sign in with email",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/sign-in/username": {
      "post": {
        "operationId": "AuthController_signInUsername",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignInDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User signed in successfully"
          }
        },
        "summary": "Sign in with username",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/sign-in/social": {
      "post": {
        "operationId": "AuthController_signInSocial",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "example": "google"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Sign in with social provider",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/social/google": {
      "post": {
        "operationId": "AuthController_googleAuth",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "idToken": {
                    "type": "string",
                    "description": "Google ID Token from One Tap"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Google One-Click Auth (ID Token)",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/sign-out": {
      "post": {
        "operationId": "AuthController_signOut",
        "parameters": [],
        "responses": {
          "200": {
            "description": "User signed out successfully"
          }
        },
        "summary": "Sign out",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/account": {
      "delete": {
        "operationId": "AuthController_deleteAccount",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Account deleted."
          },
          "400": {
            "description": "A workspace you own still has other members — transfer ownership first."
          }
        },
        "summary": "Delete your own account (and sole-member workspaces)",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/forgot-password": {
      "post": {
        "operationId": "AuthController_forgotPassword",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ForgotPasswordDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reset email sent if account exists"
          }
        },
        "summary": "Request password reset",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/resend-verification": {
      "post": {
        "operationId": "AuthController_resendVerification",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResendVerificationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verification email sent if the account exists and is unverified"
          }
        },
        "summary": "Resend the email verification link",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/reset-password": {
      "post": {
        "operationId": "AuthController_resetPassword",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset successfully"
          }
        },
        "summary": "Reset password with token",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/{path}": {
      "get": {
        "operationId": "AuthController_handleAuth_get",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "post": {
        "operationId": "AuthController_handleAuth_post",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "put": {
        "operationId": "AuthController_handleAuth_put",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "delete": {
        "operationId": "AuthController_handleAuth_delete",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "patch": {
        "operationId": "AuthController_handleAuth_patch",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "options": {
        "operationId": "AuthController_handleAuth_options",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "head": {
        "operationId": "AuthController_handleAuth_head",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      },
      "search": {
        "operationId": "AuthController_handleAuth_search",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Catch-all bridge between Express and the Better Auth (Fetch API) handler.\n\nReconstructs a standard `Request` from the incoming Express request:\nresolves a trusted origin (preferring the configured base URL over\nspoofable Host/X-Forwarded headers), copies headers and body, invokes\n`auth.handler`, then mirrors the resulting status, headers, and (notably)\nany Set-Cookie session headers back onto the Express response. Rate-limited.",
        "tags": [
          "Auth"
        ]
      }
    },
    "/auth/passkey/status": {
      "get": {
        "operationId": "PasskeyController_getStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get passkey and 2FA status",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/auth/passkey/register/start": {
      "post": {
        "operationId": "PasskeyController_startRegistration",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Start passkey registration",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/auth/passkey/register/finish": {
      "post": {
        "operationId": "PasskeyController_finishRegistration",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Finish passkey registration",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/auth/passkey/login/start": {
      "post": {
        "operationId": "PasskeyController_startLogin",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Start passkey login",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/auth/passkey/login/finish": {
      "post": {
        "operationId": "PasskeyController_finishLogin",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Finish passkey login",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/auth/passkey/disable-totp": {
      "post": {
        "operationId": "PasskeyController_disableTotp",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Disable TOTP if passkeys are enabled",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/auth/passkey/{id}": {
      "delete": {
        "operationId": "PasskeyController_deletePasskey",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Delete a passkey",
        "tags": [
          "Passkeys"
        ]
      }
    },
    "/campaigns/calendar": {
      "get": {
        "operationId": "CampaignController_getCalendar",
        "parameters": [
          {
            "name": "start",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "end",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign calendar",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/analytics/overview": {
      "get": {
        "operationId": "CampaignController_analyticsOverview",
        "parameters": [
          {
            "name": "days",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Org-wide campaign engagement overview",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns": {
      "get": {
        "operationId": "CampaignController_listCampaigns",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List campaigns",
        "tags": [
          "Campaigns"
        ]
      },
      "post": {
        "operationId": "CampaignController_createCampaign",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}": {
      "get": {
        "operationId": "CampaignController_getCampaign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign details",
        "tags": [
          "Campaigns"
        ]
      },
      "delete": {
        "operationId": "CampaignController_deleteCampaign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete campaign",
        "tags": [
          "Campaigns"
        ]
      },
      "put": {
        "operationId": "CampaignController_updateCampaign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/email": {
      "get": {
        "operationId": "CampaignController_getCampaignEmail",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign email (content + headers)",
        "tags": [
          "Campaigns"
        ]
      },
      "put": {
        "operationId": "CampaignController_updateCampaignEmail",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update campaign email (content + headers)",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/channels": {
      "put": {
        "operationId": "CampaignController_setCampaignChannels",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set smart campaign enabled channels",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/channels/{channel}/content": {
      "put": {
        "operationId": "CampaignController_setCampaignChannelContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "channel",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set smart campaign channel content",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/autosave": {
      "post": {
        "operationId": "CampaignController_autosave",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Autosave campaign draft",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/audience": {
      "put": {
        "operationId": "CampaignController_setAudience",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaignAudienceDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Attach audience to campaign",
        "tags": [
          "Campaigns"
        ]
      },
      "get": {
        "operationId": "CampaignController_getAudience",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign audience selection",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/audience/estimate": {
      "post": {
        "operationId": "CampaignController_estimateAudience",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Estimate audience recipient count",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/tracking": {
      "put": {
        "operationId": "CampaignController_setTracking",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaignTrackingDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update campaign tracking settings",
        "tags": [
          "Campaigns"
        ]
      },
      "get": {
        "operationId": "CampaignController_getTracking",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign tracking settings",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/content": {
      "put": {
        "operationId": "CampaignController_setContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update campaign email content metadata",
        "tags": [
          "Campaigns"
        ]
      },
      "get": {
        "operationId": "CampaignController_getContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign email content metadata",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/template": {
      "put": {
        "operationId": "CampaignController_setTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Attach template to campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/editor-session": {
      "get": {
        "operationId": "CampaignController_getEditorSession",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get editor session token/config",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/editor/saved": {
      "post": {
        "operationId": "CampaignController_editorSaved",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Store editor saved payload",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/editor/content": {
      "get": {
        "operationId": "CampaignController_getEditorContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get latest editor payload",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/preview": {
      "post": {
        "operationId": "CampaignController_preview",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Render campaign preview",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/send-test": {
      "post": {
        "operationId": "CampaignController_sendTest",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send test email for campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/tag-test-send": {
      "post": {
        "operationId": "CampaignController_tagTestSend",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Tag-aware test send: fire a sample with live {% tag_link %} links, ensure the recipient is a contact, and return the click-to-tag URLs so you can watch the tag land in the Audience.",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/send-preflight": {
      "get": {
        "operationId": "CampaignController_getSendPreflight",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preflight a campaign send: effective sending limits, ETA, warnings, blocked flag",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/schedule": {
      "put": {
        "operationId": "CampaignController_setSchedule",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save schedule settings",
        "tags": [
          "Campaigns"
        ]
      },
      "get": {
        "operationId": "CampaignController_getSchedule",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get schedule settings",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/validate": {
      "post": {
        "operationId": "CampaignController_validate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Validate campaign for launch",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/duplicate": {
      "post": {
        "operationId": "CampaignController_duplicate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Duplicate campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/cancel": {
      "post": {
        "operationId": "CampaignController_cancel",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel scheduled campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/pause": {
      "post": {
        "operationId": "CampaignController_pause",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pause sending campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/resume": {
      "post": {
        "operationId": "CampaignController_resume",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resume paused campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/requeue-unsent": {
      "post": {
        "operationId": "CampaignController_requeueUnsent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequeueUnsentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Re-enqueue named recipients whose send was lost",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/analytics": {
      "get": {
        "operationId": "CampaignController_getCampaignAnalytics",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Campaign engagement analytics (opens, clicks, rates)",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/events": {
      "get": {
        "operationId": "CampaignController_getEvents",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign event timeline (paginated)",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/activity": {
      "get": {
        "operationId": "CampaignController_getActivity",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Per-recipient engagement feed (opens/clicks/bounces), paginated",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/launch": {
      "post": {
        "operationId": "CampaignController_launchCampaign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Launch campaign",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/send-inapp": {
      "post": {
        "operationId": "CampaignController_sendCampaignInapp",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send campaign as in-app push to wallet audience",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/campaigns/{id}/send-inapp-test": {
      "post": {
        "operationId": "CampaignController_sendCampaignInappTest",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send the campaign's real in-app push to one wallet, for preview parity",
        "tags": [
          "Campaigns"
        ]
      }
    },
    "/analytics/campaign-runs/{id}": {
      "get": {
        "operationId": "CampaignRunsController_getRun",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Per-run analytics across channels",
        "tags": [
          "Analytics"
        ]
      }
    },
    "/campaign-types": {
      "get": {
        "operationId": "CampaignTypesController_listCampaignTypes",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List allowed campaign types",
        "tags": [
          "Campaign Types"
        ]
      }
    },
    "/t/open": {
      "get": {
        "operationId": "TrackingController_open",
        "parameters": [
          {
            "name": "campaignId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Open-tracking pixel endpoint. The recipient's mail client loads this 1x1\nGIF when the email is opened. Records a single `email.open` DeliveryEvent\n(deduped per delivery) and always returns a no-cache transparent GIF so\nsubsequent opens still hit the server.",
        "tags": [
          "Tracking"
        ]
      }
    },
    "/t/click": {
      "get": {
        "operationId": "TrackingController_click",
        "parameters": [
          {
            "name": "campaignId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "url",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sig",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Click-tracking redirect endpoint. Links in rendered emails are rewritten to\npoint here; this records an `email.click` DeliveryEvent (one per click) and\nthen 302-redirects to the original `url`. The target must carry a valid\nsignature (open-redirect guard) and be http/https.",
        "tags": [
          "Tracking"
        ]
      }
    },
    "/t/choice": {
      "get": {
        "operationId": "TrackingController_choice",
        "parameters": [
          {
            "name": "campaignId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "url",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sig",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Click-to-tag endpoint for `{% tag_link %}` (\"choose a brand\"). Verifies the\nsignature (binds campaign+delivery+tag so the tag can't be swapped), tags the\nrecipient's contact in the Audience, records a `email.click` with the choice,\nthen 302-redirects to the destination. Best-effort: a tagging failure still\nredirects, so a click never lands the recipient on an error page.",
        "tags": [
          "Tracking"
        ]
      }
    },
    "/t/unsubscribe": {
      "get": {
        "operationId": "TrackingController_unsubscribe",
        "parameters": [
          {
            "name": "campaignId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sig",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Unsubscribe endpoint hit from the email's unsubscribe link. Records a\none-time `email.unsubscribe` DeliveryEvent and flags the matching contact\nas `emailUnsubscribed` in their metadata so future sends skip them (see\nCampaignService.resolveCampaignRecipients). Optionally 302-redirects to a\nvalidated `redirect` URL, otherwise returns a plain-text confirmation.",
        "tags": [
          "Tracking"
        ]
      }
    },
    "/campaigns/{campaignId}/goals": {
      "post": {
        "operationId": "CampaignGoalsController_create",
        "parameters": [
          {
            "name": "campaignId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Create a conversion goal for a campaign",
        "tags": [
          "campaign-goals"
        ]
      },
      "get": {
        "operationId": "CampaignGoalsController_list",
        "parameters": [
          {
            "name": "campaignId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List a campaign’s goals",
        "tags": [
          "campaign-goals"
        ]
      }
    },
    "/campaigns/{campaignId}/goals/{goalId}/measure": {
      "get": {
        "operationId": "CampaignGoalsController_measure",
        "parameters": [
          {
            "name": "goalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Measure conversions for a goal within its attribution window",
        "tags": [
          "campaign-goals"
        ]
      }
    },
    "/campaigns/{campaignId}/goals/{goalId}": {
      "put": {
        "operationId": "CampaignGoalsController_update",
        "parameters": [
          {
            "name": "goalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Update a goal",
        "tags": [
          "campaign-goals"
        ]
      },
      "delete": {
        "operationId": "CampaignGoalsController_remove",
        "parameters": [
          {
            "name": "goalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Delete a goal",
        "tags": [
          "campaign-goals"
        ]
      }
    },
    "/organization/push-credentials": {
      "get": {
        "operationId": "PushCredentialController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushCredentialListDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List configured push credentials (never secrets)",
        "tags": [
          "InApp"
        ]
      }
    },
    "/organization/push-credentials/apns": {
      "put": {
        "operationId": "PushCredentialController_saveApns",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushCredentialDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload an APNs key (.p8), verified on save",
        "tags": [
          "InApp"
        ]
      }
    },
    "/organization/push-credentials/fcm": {
      "put": {
        "operationId": "PushCredentialController_saveFcm",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushCredentialDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload an FCM service account JSON, verified on save",
        "tags": [
          "InApp"
        ]
      }
    },
    "/organization/push-credentials/{provider}": {
      "delete": {
        "operationId": "PushCredentialController_remove",
        "parameters": [
          {
            "name": "provider",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemovedCountDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a push credential",
        "tags": [
          "InApp"
        ]
      }
    },
    "/inapp/push/vapid-key": {
      "get": {
        "operationId": "PushRegistrationController_getVapidKey",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VapidKeyDto"
                }
              }
            }
          }
        },
        "summary": "VAPID public key for web push subscription",
        "tags": [
          "InApp"
        ]
      }
    },
    "/inapp/push/web": {
      "post": {
        "operationId": "PushRegistrationController_registerWeb",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushRegisteredDto"
                }
              }
            }
          }
        },
        "summary": "Register a browser for web push",
        "tags": [
          "InApp"
        ]
      }
    },
    "/inapp/push/device": {
      "post": {
        "operationId": "PushRegistrationController_registerDevice",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushRegisteredDto"
                }
              }
            }
          }
        },
        "summary": "Register a mobile device token (APNs/FCM)",
        "tags": [
          "InApp"
        ]
      }
    },
    "/inapp/push": {
      "delete": {
        "operationId": "PushRegistrationController_unregister",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemovedCountDto"
                }
              }
            }
          }
        },
        "summary": "Remove a push subscription",
        "tags": [
          "InApp"
        ]
      },
      "post": {
        "operationId": "InappProtocolController_push",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InappProtocolPushDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Send an in-app push (server-to-server using sk_*)",
        "tags": [
          "InApp (Protocol)"
        ]
      }
    },
    "/inapp/challenge": {
      "post": {
        "operationId": "InappRuntimeController_challenge",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InappChallengeDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InappChallengeResponseDto"
                }
              }
            }
          }
        },
        "summary": "Get a nonce to sign (publishable-key auth)",
        "tags": [
          "InApp"
        ]
      }
    },
    "/inapp/verify": {
      "post": {
        "operationId": "InappRuntimeController_verify",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InappVerifyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InappSessionDto"
                }
              }
            }
          }
        },
        "summary": "Verify signed nonce and mint session token",
        "tags": [
          "InApp"
        ]
      }
    },
    "/integrations/inapp/status": {
      "get": {
        "operationId": "InappIntegrationsController_status",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "In-app integration status for the active organization",
        "tags": [
          "InApp Integrations"
        ]
      }
    },
    "/integrations/inapp/keys/roll": {
      "post": {
        "operationId": "InappIntegrationsController_rollKeys",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Rotate publishable SDK key(s), invalidating the old ones",
        "tags": [
          "InApp Integrations"
        ]
      }
    },
    "/integrations/inapp/origins": {
      "get": {
        "operationId": "InappIntegrationsController_listOrigins",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List allowed origins for SDK websocket connections",
        "tags": [
          "InApp Integrations"
        ]
      },
      "post": {
        "operationId": "InappIntegrationsController_addOrigin",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddAllowedOriginDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add an allowed origin",
        "tags": [
          "InApp Integrations"
        ]
      }
    },
    "/integrations/inapp/origins/{originId}": {
      "delete": {
        "operationId": "InappIntegrationsController_removeOrigin",
        "parameters": [
          {
            "name": "originId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove an allowed origin",
        "tags": [
          "InApp Integrations"
        ]
      }
    },
    "/integrations/inapp/test-push": {
      "post": {
        "operationId": "InappIntegrationsController_testPush",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InappTestPushDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send a test in-app push to a wallet",
        "tags": [
          "InApp Integrations"
        ]
      }
    },
    "/integrations/keys/secret": {
      "get": {
        "operationId": "ApiKeysController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List secret keys (masked) for the active organization",
        "tags": [
          "Integrations Keys"
        ]
      },
      "post": {
        "operationId": "ApiKeysController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSecretKeyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new secret key (returned once)",
        "tags": [
          "Integrations Keys"
        ]
      }
    },
    "/integrations/keys/secret/{keyId}": {
      "delete": {
        "operationId": "ApiKeysController_revoke",
        "parameters": [
          {
            "name": "keyId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Revoke a secret key",
        "tags": [
          "Integrations Keys"
        ]
      }
    },
    "/metrics": {
      "get": {
        "operationId": "ObservabilityController_getMetrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Prometheus scrape endpoint; emits metrics in text exposition format.",
        "tags": [
          "Observability"
        ]
      }
    },
    "/metrics/push": {
      "post": {
        "operationId": "ObservabilityController_ingestWorkerMetrics",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RelayMetricsDto"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": ""
          }
        },
        "summary": "Receive the queue worker's exposition payload so it can be merged into the\nsingle scrape target above.\n\nThe worker has no HTTP server (`NestFactory.createApplicationContext`) and\nRender background workers accept no inbound connections, so its metrics are\notherwise unreachable. Same bearer token as the scrape endpoint — this\naccepts data that ends up in the metrics feed, so it must not be more open\nthan the feed itself.\n\nThrottling is skipped: the worker pushes on a fixed 30s cadence and must\nnever be rate-limited into silence.",
        "tags": [
          "Observability"
        ]
      }
    },
    "/observability/apis": {
      "get": {
        "operationId": "ObservabilityController_getApiRuntime",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Observability"
        ]
      }
    },
    "/observability/failure-rate": {
      "get": {
        "operationId": "ObservabilityController_getFailureRate",
        "parameters": [
          {
            "name": "window",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Compact, always-on failure-rate roll-up across HTTP (5xx), BullMQ queues,\nand email delivery — for continuous polling by an uptime monitor. Result\nis memoised a few seconds server-side, so polling every few seconds is\ncheap. Optional `?window=<minutes>` sets the email lookback (default 60).",
        "tags": [
          "Observability"
        ]
      }
    },
    "/observability/modules": {
      "get": {
        "operationId": "ObservabilityController_getModuleRuntime",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Observability"
        ]
      }
    },
    "/admin/queues": {
      "get": {
        "operationId": "QueueAdminController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List registered queue names. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/queues/{name}/preview": {
      "get": {
        "operationId": "QueueAdminController_preview",
        "parameters": [
          {
            "name": "name",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Job counts by state for a queue — check before purging. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/queues/{name}/pause": {
      "post": {
        "operationId": "QueueAdminController_pause",
        "parameters": [
          {
            "name": "name",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pause a queue — workers stop taking new jobs; nothing is lost. Reversible. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/queues/{name}/resume": {
      "post": {
        "operationId": "QueueAdminController_resume",
        "parameters": [
          {
            "name": "name",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resume a paused queue. Idempotent. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/queues/{name}/purge": {
      "post": {
        "operationId": "QueueAdminController_purge",
        "parameters": [
          {
            "name": "name",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurgeQueueDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove jobs from a queue (irreversible). Requires `confirm` to echo the queue name. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/user/profile": {
      "get": {
        "operationId": "ProfileController_getProfile",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Return user profile."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get current user profile",
        "tags": [
          "User"
        ]
      },
      "put": {
        "operationId": "ProfileController_updateProfile",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProfileDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User profile updated successfully."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update current user profile",
        "tags": [
          "User"
        ]
      }
    },
    "/user/email": {
      "put": {
        "operationId": "ProfileController_requestEmailChange",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeEmailDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Request email change",
        "tags": [
          "User"
        ]
      }
    },
    "/user/email/verify": {
      "post": {
        "operationId": "ProfileController_verifyEmailChange",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyEmailDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Verify email change",
        "tags": [
          "User"
        ]
      }
    },
    "/user/password": {
      "put": {
        "operationId": "ProfileController_changePassword",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePasswordDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change password",
        "tags": [
          "User"
        ]
      }
    },
    "/user/2fa": {
      "put": {
        "operationId": "ProfileController_toggle2FA",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Toggle2faDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Toggle 2FA",
        "tags": [
          "User"
        ]
      }
    },
    "/user/2fa/setup": {
      "post": {
        "operationId": "ProfileController_setup2FA",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Setup 2FA (Get Secret)",
        "tags": [
          "User"
        ]
      }
    },
    "/user/2fa/verify": {
      "post": {
        "operationId": "ProfileController_verify2FASetup",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Verify2faDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Verify 2FA Setup",
        "tags": [
          "User"
        ]
      }
    },
    "/user/preferences/email": {
      "put": {
        "operationId": "ProfileController_updateEmailPreferences",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePreferencesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update email preferences",
        "tags": [
          "User"
        ]
      }
    },
    "/timezones": {
      "get": {
        "operationId": "TimezoneController_getTimezones",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "summary": "List supported timezones",
        "tags": [
          "Timezones"
        ]
      }
    },
    "/audience/email-verification/run": {
      "post": {
        "operationId": "AudienceController_runEmailVerification",
        "parameters": [
          {
            "name": "provider",
            "required": false,
            "in": "query",
            "description": "Third-party SMTP verifier for in-house `valid` survivors. Defaults to `EMAIL_VERIFIER_PROVIDER` (env), else `inhouse` (free). Fail-soft: an unconfigured/errored provider keeps the in-house verdict.",
            "schema": {
              "enum": [
                "inhouse",
                "kickbox",
                "zerobounce"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Verify the next batch of unverified contact emails (in-house syntax/typo/disposable/role/MX+A) — call until remaining=0. Pass ?provider=kickbox to SMTP-verify the in-house survivors.",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/email-verification/status": {
      "get": {
        "operationId": "AudienceController_emailVerificationStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Org-wide email verification tallies",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/lists": {
      "get": {
        "operationId": "AudienceController_listLists",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List selectable audience lists (aliased to segments)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/segments": {
      "get": {
        "operationId": "AudienceController_listSegments",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List selectable audience segments",
        "tags": [
          "Audience"
        ]
      },
      "post": {
        "operationId": "AudienceController_createSegment",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create audience segment",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/segments/{id}": {
      "get": {
        "operationId": "AudienceController_getSegment",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get one list (segment) with a page of its members",
        "tags": [
          "Audience"
        ]
      },
      "patch": {
        "operationId": "AudienceController_renameSegment",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Rename a list (segment)",
        "tags": [
          "Audience"
        ]
      },
      "delete": {
        "operationId": "AudienceController_deleteSegment",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a list (contacts and tag are kept)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/segments/{id}/members": {
      "post": {
        "operationId": "AudienceController_addSegmentMembers",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add contacts to a list (attaches the list’s backing tag — same mechanism capture forms use)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/segments/{id}/members/{profileId}": {
      "delete": {
        "operationId": "AudienceController_removeSegmentMember",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "profileId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove one contact from a list",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/sync": {
      "post": {
        "operationId": "AudienceController_startWalletSync",
        "parameters": [],
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sync wallets — queue on-chain re-enrichment for every wallet-bearing contact (async; poll GET /audience/sync)",
        "tags": [
          "Audience"
        ]
      },
      "get": {
        "operationId": "AudienceController_getWalletSync",
        "parameters": [
          {
            "name": "jobId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Wallet sync status (most recent run, or ?jobId= a specific one)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/overview": {
      "get": {
        "operationId": "AudienceController_getOverview",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get audience overview stats",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/suppressed": {
      "get": {
        "operationId": "AudienceController_listSuppressed",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List suppressed contacts (unsubscribed / bounced / complained), paginated",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/report": {
      "get": {
        "operationId": "AudienceController_getReport",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Chart-ready audience report: totals, reachability, growth, engagement, top segments",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/reengagement-count": {
      "get": {
        "operationId": "AudienceController_getReengagementCount",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get count of profiles needing re-engagement",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/health-score": {
      "get": {
        "operationId": "AudienceController_getHealthScore",
        "parameters": [
          {
            "name": "profileId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Health score calculation details (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/automation/suggestions": {
      "get": {
        "operationId": "AudienceController_getAutomationSuggestions",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Automation suggestions (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles": {
      "get": {
        "operationId": "AudienceController_listContacts",
        "parameters": [
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "verified",
                "pending",
                "unverified"
              ],
              "type": "string"
            }
          },
          {
            "name": "tag",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "engagement",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "active",
                "cooling",
                "cold"
              ],
              "type": "string"
            }
          },
          {
            "name": "hasWallet",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "name",
                "healthScore",
                "lastActionAt"
              ],
              "type": "string"
            }
          },
          {
            "name": "direction",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "name": "include",
            "required": false,
            "in": "query",
            "description": "Comma-separated: wallets,tags,attributes,lastAction,health (legacy: wallet)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "required": false,
            "in": "query",
            "description": "Comma-separated allowlist of response fields",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List contacts/profiles",
        "tags": [
          "Audience"
        ]
      },
      "post": {
        "operationId": "AudienceController_createContact",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create new contact",
        "tags": [
          "Audience"
        ]
      },
      "delete": {
        "operationId": "AudienceController_deleteAllContacts",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete ALL contacts in the organization (requires confirmCount)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/pii/backfill": {
      "post": {
        "operationId": "AudienceController_backfillPii",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Backfill contact PII protection (blind index + at-rest ciphertext). Bounded; call until done=true.",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}": {
      "get": {
        "operationId": "AudienceController_getContact",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include",
            "required": false,
            "in": "query",
            "description": "Comma-separated: wallets,tags,attributes,lastAction,health (legacy: wallet)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact details",
        "tags": [
          "Audience"
        ]
      },
      "put": {
        "operationId": "AudienceController_updateContact",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update contact",
        "tags": [
          "Audience"
        ]
      },
      "delete": {
        "operationId": "AudienceController_deleteContact",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete contact",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/activity": {
      "get": {
        "operationId": "AudienceController_getContactActivity",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "types",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact activity timeline",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/emails": {
      "get": {
        "operationId": "AudienceController_getContactEmails",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "campaignId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact email history",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/dapp-stats": {
      "get": {
        "operationId": "AudienceController_getContactDappStats",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact dapp/onchain stats (derived)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/balances": {
      "get": {
        "operationId": "AudienceController_getContactBalances",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "noSpam",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact wallet balances (GoldRush-backed; cached)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/transactions": {
      "get": {
        "operationId": "AudienceController_getContactTransactions",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "fromBlock",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toBlock",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact transactions (GoldRush-backed; cached)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/contract-activity": {
      "get": {
        "operationId": "AudienceController_getContactContractActivity",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chain",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact contract activity (GoldRush-backed)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/enrich": {
      "post": {
        "operationId": "AudienceController_enrichContact",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Trigger onchain enrichment refresh (background)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/health": {
      "get": {
        "operationId": "AudienceController_getContactHealth",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact health score + breakdown",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/churn": {
      "get": {
        "operationId": "AudienceController_getContactChurn",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact churn prediction",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/attributes": {
      "get": {
        "operationId": "AudienceController_listAttributes",
        "parameters": [
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List audience attribute keys (schema)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/attributes/keys": {
      "get": {
        "operationId": "AudienceController_listAttributeKeysAlias",
        "parameters": [
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List audience attribute keys (schema)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/attributes/{key}/values": {
      "get": {
        "operationId": "AudienceController_listAttributeValues",
        "parameters": [
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List distinct values for an attribute key",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/tags": {
      "get": {
        "operationId": "AudienceController_listTags",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List tags",
        "tags": [
          "Audience"
        ]
      },
      "post": {
        "operationId": "AudienceController_createTag",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create tag",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/tags": {
      "put": {
        "operationId": "AudienceController_addTags",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add tags to contact",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/tags/{tagId}": {
      "patch": {
        "operationId": "AudienceController_renameTag",
        "parameters": [
          {
            "name": "tagId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Rename a tag",
        "tags": [
          "Audience"
        ]
      },
      "delete": {
        "operationId": "AudienceController_deleteTag",
        "parameters": [
          {
            "name": "tagId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "force",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a tag (refuses if it backs a list)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/profiles/{id}/tags/{tagName}": {
      "delete": {
        "operationId": "AudienceController_removeTag",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tagName",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove tag from contact",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/fields": {
      "get": {
        "operationId": "AudienceController_listAudienceFields",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available audience/profile fields for mapping (email, name, wallet, custom fields, tags)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/sample/csv": {
      "get": {
        "operationId": "AudienceController_downloadImportSampleCsv",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download sample audience import CSV template",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/sample/json": {
      "get": {
        "operationId": "AudienceController_downloadImportSampleJson",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download sample audience import JSON template",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import": {
      "post": {
        "deprecated": true,
        "description": "Deprecated: streams the whole file through the backend (subject to the proxy body cap). For large files use the presigned SAS flow — POST /audience/imports/upload-url then POST /audience/imports with { blobPath }. Kept for back-compat.",
        "operationId": "AudienceController_importLegacy",
        "parameters": [],
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Import multiple profiles (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/upload": {
      "post": {
        "deprecated": true,
        "description": "Deprecated: streams the whole file through the backend (subject to the proxy body cap). For large files use the presigned SAS flow — POST /audience/imports/upload-url then POST /audience/imports with { blobPath }. Kept for back-compat.",
        "operationId": "AudienceController_importContacts",
        "parameters": [],
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload import file (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/{id}/status": {
      "get": {
        "operationId": "AudienceController_getImportStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get import status (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/recent": {
      "get": {
        "operationId": "AudienceController_listRecentImports",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List recent imports (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/{id}": {
      "get": {
        "operationId": "AudienceController_getImportDetail",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get import details (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/{id}/errors": {
      "get": {
        "operationId": "AudienceController_getImportErrors",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get import errors (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/{id}/map": {
      "post": {
        "operationId": "AudienceController_mapImport",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Map import columns (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/import/{id}/confirm": {
      "post": {
        "operationId": "AudienceController_confirmImport",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Confirm import (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export": {
      "post": {
        "operationId": "AudienceController_exportContacts",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAudienceExportJobDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start export job (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/verify-emails": {
      "post": {
        "operationId": "AudienceController_verifyEmails",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "DNS-verify contact email domains (MX) and flag undeliverable addresses",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/verify-emails/bulk/quote": {
      "get": {
        "operationId": "AudienceController_quoteBulkVerification",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cost and size of a bulk mailbox verification before committing to it",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/verify-emails/bulk": {
      "post": {
        "operationId": "AudienceController_startBulkVerification",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Queue mailbox-level verification (paid) across the existing audience",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export/options": {
      "get": {
        "operationId": "AudienceController_getExportOptions",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available export options (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export/{exportId}/status": {
      "get": {
        "operationId": "AudienceController_getLegacyExportStatus",
        "parameters": [
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get export status (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export/status/{exportId}": {
      "get": {
        "operationId": "AudienceController_getLegacyExportStatusAlt",
        "parameters": [
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get export status (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export/download/{exportId}": {
      "get": {
        "operationId": "AudienceController_downloadLegacyExport",
        "parameters": [
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download export file (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export/recent": {
      "get": {
        "operationId": "AudienceController_getRecentExports",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get recent exports (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/export/{exportId}": {
      "get": {
        "operationId": "AudienceController_getExportDetail",
        "parameters": [
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get export details (legacy alias)",
        "tags": [
          "Audience"
        ]
      },
      "delete": {
        "operationId": "AudienceController_deleteExport",
        "parameters": [
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete export (legacy alias)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/presets": {
      "get": {
        "operationId": "AudienceController_listImportPresets",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List platform import presets",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/upload-url": {
      "post": {
        "operationId": "AudienceController_createImportUploadUrl",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateImportUploadUrlDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a presigned SAS URL to upload a large import file directly to blob storage",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports": {
      "post": {
        "operationId": "AudienceController_createImportJob",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlobImportDto"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlobImportDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create import job (CSV/JSON) — multipart file OR JSON { blobPath } from a presigned SAS upload",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/{jobId}": {
      "get": {
        "operationId": "AudienceController_getImportJobStatus",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get import job status",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/{jobId}/errors": {
      "get": {
        "operationId": "AudienceController_downloadImportErrors",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download import error report (CSV)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/{jobId}/rejected.csv": {
      "get": {
        "operationId": "AudienceController_downloadImportRejected",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download the bad (thrown-out) addresses from an import (CSV)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/{jobId}/suppressed.csv": {
      "get": {
        "operationId": "AudienceController_downloadImportSuppressed",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download the pre-existing-suppressed addresses from an import (CSV)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/imports/{jobId}/cancel": {
      "post": {
        "operationId": "AudienceController_cancelImportJob",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel import job",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/exports": {
      "post": {
        "operationId": "AudienceController_createExportJob",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAudienceExportJobDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create export job (CSV/JSON)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/exports/{jobId}": {
      "get": {
        "operationId": "AudienceController_getExportJobStatus",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get export job status",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/exports/{jobId}/download": {
      "get": {
        "operationId": "AudienceController_downloadExport",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download export file",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/exports/{jobId}/cancel": {
      "post": {
        "operationId": "AudienceController_cancelExportJob",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel export job",
        "tags": [
          "Audience"
        ]
      }
    },
    "/segments/reachable": {
      "get": {
        "operationId": "SegmentsReachableController_reachable",
        "parameters": [
          {
            "name": "reachable_on",
            "required": false,
            "in": "query",
            "schema": {
              "example": "inapp,email",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "example": 100,
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "example": "0xabc...",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resolve reachable wallets by channel filter",
        "tags": [
          "Segments"
        ]
      }
    },
    "/analytics/reports/holder-distribution": {
      "get": {
        "operationId": "AnalyticsController_holderDistribution",
        "parameters": [
          {
            "name": "token",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Token holder distribution, top holders, concentration",
        "tags": [
          "analytics"
        ]
      }
    },
    "/analytics/reports/retention-cohorts": {
      "get": {
        "operationId": "AnalyticsController_retentionCohorts",
        "parameters": [
          {
            "name": "weeks",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Weekly signup cohorts and their retention curve",
        "tags": [
          "analytics"
        ]
      }
    },
    "/analytics/reports/engagement-by-segment": {
      "get": {
        "operationId": "AnalyticsController_engagementBySegment",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Per-segment email engagement (sent / open / click)",
        "tags": [
          "analytics"
        ]
      }
    },
    "/analytics/reports/campaign-report": {
      "get": {
        "operationId": "AnalyticsController_campaignReport",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Per-campaign delivery + engagement rows",
        "tags": [
          "analytics"
        ]
      }
    },
    "/analytics/reports/automation-performance": {
      "get": {
        "operationId": "AnalyticsController_automationPerformance",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Per-flow enrolments + delivery + engagement rows",
        "tags": [
          "analytics"
        ]
      }
    },
    "/audience/suppressions": {
      "get": {
        "operationId": "SuppressionController_list",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Email substring filter",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List suppressed email contacts (auto-populates the \"Suppressed emails\" list)",
        "tags": [
          "Audience"
        ]
      },
      "post": {
        "operationId": "SuppressionController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSuppressionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Manually suppress an email address (opt-out / known-bad address)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/audience/suppressions/{contactId}": {
      "delete": {
        "operationId": "SuppressionController_remove",
        "parameters": [
          {
            "name": "contactId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Un-suppress a contact (remove tag + clear suppression metadata)",
        "tags": [
          "Audience"
        ]
      }
    },
    "/admin/deliverability/{domain}/freeze": {
      "post": {
        "operationId": "AdminController_freezeDomain",
        "parameters": [
          {
            "name": "domain",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Freeze a sender domain — parks every send from it. Reversible. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/deliverability/{domain}/unfreeze": {
      "post": {
        "operationId": "AdminController_unfreezeDomain",
        "parameters": [
          {
            "name": "domain",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Unfreeze a sender domain. Idempotent. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/{orgId}/adjust-credit": {
      "post": {
        "operationId": "AdminController_adjustCredit",
        "parameters": [
          {
            "name": "orgId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Adjust an org prepaid credit balance (signed grant/clawback, or reset:true to zero). Audited. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/organizations": {
      "get": {
        "operationId": "AdminController_listOrganizations",
        "parameters": [
          {
            "name": "query",
            "required": false,
            "in": "query",
            "description": "Name search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Default 1",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Default 50",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List every organization (Organizations page + org-name picker). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/deliverability/offenders": {
      "get": {
        "operationId": "AdminController_deliverabilityOffenders",
        "parameters": [
          {
            "name": "window",
            "required": false,
            "in": "query",
            "description": "Window in days (default 30, max 90)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Top N orgs (default 20, max 100)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "minSample",
            "required": false,
            "in": "query",
            "description": "Min events to flag (default 50)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reputation triage: worst-offending orgs by 30d bounce/complaint, each broken down by sender domain + provider. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/users": {
      "get": {
        "operationId": "AdminController_listUsers",
        "parameters": [
          {
            "name": "query",
            "required": false,
            "in": "query",
            "description": "Email search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Default 1",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Default 50",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List platform users (Users page). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/audit": {
      "get": {
        "operationId": "AdminController_listAuditLog",
        "parameters": [
          {
            "name": "path",
            "required": false,
            "in": "query",
            "description": "Path substring filter (e.g. \"billing\")",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "required": false,
            "in": "query",
            "description": "ISO lower bound (createdAt >=)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "required": false,
            "in": "query",
            "description": "ISO upper bound (createdAt <=)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Default 1",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Default 50, max 200",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Platform-admin access log (append-only): every authorized admin request, newest first. Filter by path substring + since/until. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/goldrush/usage": {
      "get": {
        "operationId": "AdminPlatformMetricsController_goldrushUsage",
        "parameters": [
          {
            "name": "window",
            "required": false,
            "in": "query",
            "description": "Window in days (default 30, min 1, max 365)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "GoldRush (on-chain data API) credit usage across every org for the window: total, average, top orgs, and remaining vs the upstream account cap. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/ses/quota": {
      "get": {
        "operationId": "AdminPlatformMetricsController_sesQuota",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "AWS SES account send quota + 24h usage (SESv2 GetAccount) plus marketing daily cap/usage. Fail-soft (never 500). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/summary": {
      "get": {
        "operationId": "AdminPlatformMetricsController_billingSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Money-wise billing snapshot: total orgs, plan distribution, estimated MRR (catalog list price), PAYG wallet total, and top spenders. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/email/summary": {
      "get": {
        "operationId": "AdminActivityMetricsController_emailSummary",
        "parameters": [
          {
            "name": "window",
            "required": false,
            "in": "query",
            "description": "Window in days (default 30, max 90)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Platform email health over a trailing window (all orgs): totals, delivery/bounce/complaint rates, and the top failing orgs/domains/reasons. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/users/metrics": {
      "get": {
        "operationId": "AdminActivityMetricsController_userMetrics",
        "parameters": [
          {
            "name": "window",
            "required": false,
            "in": "query",
            "description": "Window in days (default 30, max 90)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Platform user activity over a trailing window (all orgs): total users, new signups (+delta), daily logins, active users, and cohort retention. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/billing/card/setup-intent": {
      "post": {
        "operationId": "BillingController_createCardSetupIntent",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardSetupIntentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a SetupIntent to save a card for auto-charge (off-session)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/card-on-file": {
      "get": {
        "operationId": "BillingController_cardOnFile[0]",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The organization's saved card, if any",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/card": {
      "get": {
        "operationId": "BillingController_cardOnFile[1]",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The organization's saved card, if any",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/upgrade": {
      "post": {
        "operationId": "BillingController_createUpgradeCheckout",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create upgrade checkout session",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/upgrade/blockradar": {
      "post": {
        "operationId": "BillingController_createBlockradarUpgrade",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUpgradeCheckoutDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Blockradar stablecoin checkout (dynamic pricing)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/checkout/plan": {
      "post": {
        "operationId": "BillingController_createPlanCheckout",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePlanCheckoutDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a crypto (Blockradar) or card (Stripe) checkout for an org plan, monthly or annual",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payg/start": {
      "post": {
        "operationId": "BillingController_startPayg",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Switch the active org to pay-as-you-go (one-time trial credit included)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payg/wallet/{organizationId}": {
      "get": {
        "operationId": "BillingController_getPaygWallet",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "PAYG wallet: balance, unit rates, recent ledger entries",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/contact-pricing": {
      "get": {
        "operationId": "BillingController_quoteContactPricing",
        "parameters": [
          {
            "name": "contacts",
            "required": false,
            "in": "query",
            "schema": {
              "example": 25000,
              "type": "string"
            }
          },
          {
            "name": "tier",
            "required": false,
            "in": "query",
            "description": "Which tier to echo as the headline. All three are priced regardless.",
            "schema": {
              "enum": [
                "launch",
                "growth",
                "pro"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Price a contact count (slider): every Suite tier at that size, on the pricing curve",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/quote": {
      "get": {
        "operationId": "BillingController_quote",
        "parameters": [
          {
            "name": "plan",
            "required": true,
            "in": "query",
            "description": "Which line. For suite the TIER is derived from `units`, not chosen.",
            "schema": {
              "enum": [
                "suite",
                "send"
              ],
              "type": "string"
            }
          },
          {
            "name": "units",
            "required": true,
            "in": "query",
            "description": "Contacts for Suite, subscribers for Send.",
            "schema": {
              "example": 25000,
              "type": "string"
            }
          },
          {
            "name": "extraSeats",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "billingCycle",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Price a size on either line: ?plan=suite (contacts, tier derived) or ?plan=send (subscribers)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/checkout/credits": {
      "post": {
        "operationId": "BillingController_createCreditTopup",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditTopupDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a crypto or card checkout that tops up the org PAYG wallet ($10–$1000)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/plan-usage/{organizationId}": {
      "get": {
        "operationId": "BillingController_getPlanUsage",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Current plan, tier limits, and live usage meters (contacts, emails, AI + wallet-data credits, seats, automations, API keys)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/upgrade/{reference}/cancel": {
      "post": {
        "operationId": "BillingController_cancelPendingUpgrade",
        "parameters": [
          {
            "name": "reference",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel your own pending checkout (clears the waiting-for-payment state)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/upgrade/blockradar/{reference}": {
      "get": {
        "operationId": "BillingController_getBlockradarUpgradeStatus",
        "parameters": [
          {
            "name": "reference",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check status of a Blockradar upgrade (polling support)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing": {
      "get": {
        "operationId": "BillingController_getBillingInfo",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get billing info and usage",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/auto-optimize": {
      "put": {
        "operationId": "BillingController_toggleAutoOptimize",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ToggleAutoOptimizeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Toggle auto-optimize feature",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/usage": {
      "get": {
        "operationId": "BillingController_getUsage",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "current",
                "month"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get detailed usage breakdown",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/plan": {
      "get": {
        "operationId": "BillingController_getPlanSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get current plan details + available upgrade options",
        "tags": [
          "Billing"
        ]
      },
      "put": {
        "operationId": "BillingController_changePlan",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePlanDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change subscription plan",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/plans": {
      "get": {
        "operationId": "BillingController_getPlans",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available plans",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/blockradar/history": {
      "get": {
        "operationId": "BillingController_getBlockradarHistory",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List past Blockradar (crypto) payments",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/blockradar/transactions": {
      "get": {
        "operationId": "BillingController_getBlockradarTransactions",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List all Blockradar transactions",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payment-method": {
      "get": {
        "operationId": "BillingController_getPaymentMethod",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get current payment methods",
        "tags": [
          "Billing"
        ]
      },
      "put": {
        "operationId": "BillingController_updatePaymentMethod",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePaymentMethodDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update payment method",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payment-methods": {
      "get": {
        "operationId": "BillingController_getPaymentMethods",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List all saved payment methods (cards + crypto wallets)",
        "tags": [
          "Billing"
        ]
      },
      "post": {
        "operationId": "BillingController_addPaymentMethod",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentMethodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add new payment method (card or crypto address)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payment-methods/default": {
      "put": {
        "operationId": "BillingController_setDefaultPaymentMethod",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDefaultPaymentMethodDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set default payment method",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payment-methods/{id}": {
      "delete": {
        "operationId": "BillingController_deletePaymentMethodV2",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a payment method",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/payment-method/{id}": {
      "delete": {
        "operationId": "BillingController_deletePaymentMethod",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a payment method",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/invoices": {
      "get": {
        "operationId": "BillingController_getInvoices",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List invoices",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/invoices/{id}": {
      "get": {
        "operationId": "BillingController_getInvoice",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get invoice details",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/invoices/{id}/pdf": {
      "get": {
        "operationId": "BillingController_getInvoicePdf",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stream invoice PDF",
        "tags": [
          "Billing"
        ]
      }
    },
    "/billing/invoices/{id}/download": {
      "get": {
        "operationId": "BillingController_downloadInvoice",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get signed download URL for PDF invoice",
        "tags": [
          "Billing"
        ]
      }
    },
    "/webhook/blockradar": {
      "post": {
        "operationId": "WebhookController_handleBlockradarWebhook",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Handle Blockradar payment webhooks",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/webhook/stripe": {
      "post": {
        "operationId": "WebhookController_handleStripeWebhook",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Handle Stripe payment webhooks (card checkout)",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/admin/billing/invoices": {
      "post": {
        "operationId": "AdminDunningController_createInvoice",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a collectible invoice + reminder ladder (dunning). Admin-key only.",
        "tags": [
          "Admin"
        ]
      },
      "get": {
        "operationId": "AdminDunningController_listInvoices",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List an org’s collectible invoices + reminders. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/invoices/{invoiceId}/delivery": {
      "get": {
        "operationId": "AdminDunningController_invoiceDelivery",
        "parameters": [
          {
            "name": "invoiceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delivery status of an invoice’s reminder emails (sent → delivered/bounced/…). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/invoices/{invoiceId}/auto-charge": {
      "post": {
        "operationId": "AdminDunningController_setAutoCharge",
        "parameters": [
          {
            "name": "invoiceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enable/disable off-session card auto-charge on an invoice. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/invoices/{invoiceId}/paid": {
      "post": {
        "operationId": "AdminDunningController_markPaid",
        "parameters": [
          {
            "name": "invoiceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark an invoice paid (stops further reminders). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/invoices/{invoiceId}/void": {
      "post": {
        "operationId": "AdminDunningController_voidInvoice",
        "parameters": [
          {
            "name": "invoiceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Void an invoice (cancels the debt + reminders). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/billing/dunning/run": {
      "post": {
        "operationId": "AdminDunningController_runDunning",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Run the dunning sweep now (sends due reminders, escalates overdue). Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/pricing": {
      "get": {
        "operationId": "AdminPricingController_catalogue",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The full pricing catalogue: curve inputs, both product lines, allowances and the overage rate card. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/pricing/suite": {
      "get": {
        "operationId": "AdminPricingController_quoteSuite",
        "parameters": [
          {
            "name": "contacts",
            "required": true,
            "in": "query",
            "schema": {
              "example": 25000,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Price a Suite contact count; the tier is derived from it. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/admin/pricing/send": {
      "get": {
        "operationId": "AdminPricingController_quoteSend",
        "parameters": [
          {
            "name": "subscribers",
            "required": true,
            "in": "query",
            "schema": {
              "example": 10000,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Price a Send subscriber count. Admin-key only.",
        "tags": [
          "Admin"
        ]
      }
    },
    "/public/pricing/plans": {
      "get": {
        "operationId": "PricingPublicController_plans",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Public lineup: plan names, shelf prices and headline capability",
        "tags": [
          "pricing (public)"
        ]
      }
    },
    "/public/pricing/quote": {
      "get": {
        "operationId": "PricingPublicController_quote",
        "parameters": [
          {
            "name": "plan",
            "required": true,
            "in": "query",
            "description": "Which line. For suite the tier is derived from `units`.",
            "schema": {
              "enum": [
                "suite",
                "send"
              ],
              "type": "string"
            }
          },
          {
            "name": "units",
            "required": true,
            "in": "query",
            "schema": {
              "example": 16000,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Price a size publicly: ?plan=suite (contacts, tier derived) or ?plan=send (subscribers)",
        "tags": [
          "pricing (public)"
        ]
      }
    },
    "/storage/provision": {
      "post": {
        "operationId": "StorageController_provision",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Provision storage containers and configure CORS using Azure SDK",
        "tags": [
          "Storage"
        ]
      }
    },
    "/storage/upload/sync": {
      "post": {
        "operationId": "StorageController_uploadSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Synchronous upload to Azure Blob Storage with validation",
        "tags": [
          "Storage"
        ]
      }
    },
    "/storage/upload/async": {
      "post": {
        "operationId": "StorageController_uploadAsync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Asynchronous upload via queue with retries",
        "tags": [
          "Storage"
        ]
      }
    },
    "/storage/files": {
      "get": {
        "operationId": "StorageController_listFiles",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List uploaded files with metadata",
        "tags": [
          "Storage"
        ]
      }
    },
    "/storage/files/{id}": {
      "get": {
        "operationId": "StorageController_getFile",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get file details and download URL",
        "tags": [
          "Storage"
        ]
      }
    },
    "/onboarding/progress": {
      "get": {
        "operationId": "OnboardingController_getProgress",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get onboarding progress for current user",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/onboarding/tasks": {
      "get": {
        "operationId": "OnboardingController_listTasks",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List onboarding tasks for current user",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/onboarding/tasks/{taskId}/complete": {
      "put": {
        "operationId": "OnboardingController_completeTask",
        "parameters": [
          {
            "name": "taskId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteOnboardingTaskDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark onboarding task as completed",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/onboarding/suggest-contracts": {
      "post": {
        "operationId": "OnboardingController_suggestContracts",
        "parameters": [],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Suggests which contracts to register and which events to listen on for a\nprotocol, from its name + sector (picked during onboarding). LLM-assisted\nwith deterministic sector defaults as the floor; every suggestion requires\nhuman review before use.",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/onboarding/track": {
      "post": {
        "operationId": "OnboardingController_track",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TrackOnboardingDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Track onboarding step event",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/onboarding/complete": {
      "post": {
        "operationId": "OnboardingController_complete",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteOnboardingDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark onboarding as completed",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/onboarding/admin/summary": {
      "get": {
        "operationId": "OnboardingController_adminSummary",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Admin onboarding summary metrics",
        "tags": [
          "Onboarding"
        ]
      }
    },
    "/templates/public": {
      "get": {
        "operationId": "TemplateController_listPublicTemplates",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tags",
            "required": false,
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List public templates",
        "tags": [
          "Templates"
        ]
      }
    },
    "/templates/public/{id}": {
      "get": {
        "operationId": "TemplateController_getPublicTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get public template details",
        "tags": [
          "Templates"
        ]
      }
    },
    "/templates/clone": {
      "post": {
        "operationId": "TemplateController_clonePublicTemplate",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Clone a public template into org templates",
        "tags": [
          "Templates"
        ]
      }
    },
    "/templates": {
      "get": {
        "operationId": "TemplateController_listTemplates",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "folder",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "channel",
            "required": false,
            "in": "query",
            "description": "Filter by delivery channel: email | inapp",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List templates",
        "tags": [
          "Templates"
        ]
      },
      "post": {
        "operationId": "TemplateController_createTemplate",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create template",
        "tags": [
          "Templates"
        ]
      }
    },
    "/templates/{id}": {
      "get": {
        "operationId": "TemplateController_getTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get template details",
        "tags": [
          "Templates"
        ]
      },
      "put": {
        "operationId": "TemplateController_updateTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update template",
        "tags": [
          "Templates"
        ]
      },
      "delete": {
        "operationId": "TemplateController_deleteTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete template",
        "tags": [
          "Templates"
        ]
      }
    },
    "/email-templates": {
      "get": {
        "operationId": "EmailTemplateController_list",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "access",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tags",
            "required": false,
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List accessible templates (public + your private templates)",
        "tags": [
          "Email Templates"
        ]
      },
      "post": {
        "operationId": "EmailTemplateController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a private template (owned by you)",
        "tags": [
          "Email Templates"
        ]
      }
    },
    "/email-templates/{id}": {
      "get": {
        "operationId": "EmailTemplateController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get template (public or owned private)",
        "tags": [
          "Email Templates"
        ]
      },
      "put": {
        "operationId": "EmailTemplateController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update template (owned private; public is admin-only)",
        "tags": [
          "Email Templates"
        ]
      },
      "delete": {
        "operationId": "EmailTemplateController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete template (owned private; public is admin-only)",
        "tags": [
          "Email Templates"
        ]
      }
    },
    "/email-templates/{id}/clone": {
      "post": {
        "operationId": "EmailTemplateController_clone",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Clone a public template into your private workspace",
        "tags": [
          "Email Templates"
        ]
      }
    },
    "/email-templates/{id}/publish": {
      "post": {
        "operationId": "EmailTemplateController_publish",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish a template to the shared public gallery, visible to all users (platform admin only)",
        "tags": [
          "Email Templates"
        ]
      }
    },
    "/email-templates/{id}/unpublish": {
      "post": {
        "operationId": "EmailTemplateController_unpublish",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a template from the public gallery (back to private; platform admin only)",
        "tags": [
          "Email Templates"
        ]
      }
    },
    "/email-builder/config": {
      "get": {
        "operationId": "EmailBuilderController_getConfig",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Returns supported merge tag keys, types, and filters."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get dynamic variable catalog for the email builder",
        "tags": [
          "Email Builder"
        ]
      }
    },
    "/identity/stats": {
      "get": {
        "operationId": "IdentityController_stats",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Identity overview stats (dashboard)",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/events": {
      "get": {
        "operationId": "IdentityController_events",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Recent identity events (dashboard)",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/register": {
      "post": {
        "operationId": "IdentityController_register",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterIdentityDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Register wallet into the protocol identity system",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/protocol-salt": {
      "get": {
        "operationId": "IdentityController_protocolSalt",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Fetch per-protocol identity salt",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/group/{kind}/state": {
      "get": {
        "operationId": "IdentityController_groupState",
        "parameters": [
          {
            "name": "kind",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "segmentId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Fetch identity group state for proof generation",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/status": {
      "get": {
        "operationId": "IdentityController_status",
        "parameters": [
          {
            "name": "walletAddress",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Get identity status for a wallet",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/otp": {
      "post": {
        "operationId": "IdentityController_issueOtp",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IssueIdentityOtpDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Issue OTP for channel binding",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/bind": {
      "post": {
        "operationId": "IdentityController_bind",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BindIdentityDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Bind wallet to channel handle (encrypted)",
        "tags": [
          "Identity"
        ]
      }
    },
    "/identity/decrypt": {
      "post": {
        "operationId": "IdentityController_decrypt",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecryptIdentityDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Decrypt PII for send workers (server-to-server)",
        "tags": [
          "Identity"
        ]
      }
    },
    "/indexing/jobs": {
      "post": {
        "operationId": "IndexingController_createJob",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateIndexingJobDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create indexing job",
        "tags": [
          "Indexing"
        ]
      }
    },
    "/indexing/jobs/{jobId}": {
      "get": {
        "operationId": "IndexingController_getJob",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get indexing job",
        "tags": [
          "Indexing"
        ]
      }
    },
    "/indexing/jobs/{jobId}/cancel": {
      "post": {
        "operationId": "IndexingController_cancelJob",
        "parameters": [
          {
            "name": "jobId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel indexing job",
        "tags": [
          "Indexing"
        ]
      }
    },
    "/indexing/protocols/{protocolId}/status": {
      "get": {
        "description": "`protocolId` must equal the active org id, otherwise rejected.",
        "operationId": "IndexingController_protocolStatus",
        "parameters": [
          {
            "name": "protocolId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get protocol indexing status",
        "tags": [
          "Indexing"
        ]
      }
    },
    "/indexing/protocols/{protocolId}/reindex": {
      "post": {
        "description": "`protocolId` must equal the active org id, otherwise rejected.",
        "operationId": "IndexingController_reindex",
        "parameters": [
          {
            "name": "protocolId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reindex protocol (enqueue new job)",
        "tags": [
          "Indexing"
        ]
      }
    },
    "/dashboard/home": {
      "get": {
        "operationId": "DashboardController_home",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dashboard home aggregated data",
        "tags": [
          "Dashboard"
        ]
      }
    },
    "/dashboard/overview": {
      "get": {
        "operationId": "DashboardController_overview",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dashboard headline metrics (4 cards + deltas)",
        "tags": [
          "Dashboard"
        ]
      }
    },
    "/dashboard/featured-automation": {
      "get": {
        "operationId": "DashboardController_featuredAutomation",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dashboard featured automation card",
        "tags": [
          "Dashboard"
        ]
      }
    },
    "/onchain/activity/recent": {
      "get": {
        "operationId": "OnchainActivityController_recent",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Recent on-chain activity feed",
        "tags": [
          "On-chain"
        ]
      }
    },
    "/query/search": {
      "get": {
        "operationId": "AiQueryController_search",
        "parameters": [
          {
            "name": "query",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "topK",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Semantic search over ingested site content (no LLM)",
        "tags": [
          "AI Query"
        ]
      }
    },
    "/query/text": {
      "post": {
        "operationId": "AiQueryController_queryText",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryTextDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Process a text query through the RAG pipeline",
        "tags": [
          "AI Query"
        ]
      }
    },
    "/query/voice": {
      "post": {
        "operationId": "AiQueryController_queryVoice",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryVoiceDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Process a voice (pre-transcribed) query through the RAG pipeline",
        "tags": [
          "AI Query"
        ]
      }
    },
    "/query/text/stream": {
      "get": {
        "operationId": "AiQueryController_streamText",
        "parameters": [
          {
            "name": "query",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mode",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stream a text query response (SSE)",
        "tags": [
          "AI Query"
        ]
      }
    },
    "/ai/metrics": {
      "get": {
        "operationId": "AiAdminController_getMetrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "AI metrics snapshot (org admin)",
        "tags": [
          "AI Admin"
        ]
      }
    },
    "/ai/feedback": {
      "post": {
        "operationId": "AiAdminController_submitFeedback",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AiFeedbackDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Submit feedback for an AI response",
        "tags": [
          "AI Admin"
        ]
      }
    },
    "/ai/ingest/web": {
      "post": {
        "operationId": "AiAdminController_ingestWeb",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestWebDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest website content into the vector store (dashboard)",
        "tags": [
          "AI Admin"
        ]
      }
    },
    "/ai/ingest/files": {
      "post": {
        "operationId": "AiAdminController_ingestFiles",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest uploaded files into the vector store (dashboard)",
        "tags": [
          "AI Admin"
        ]
      }
    },
    "/ai/reindex": {
      "post": {
        "operationId": "AiAdminController_reindex",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Trigger incremental re-index for web sources (dashboard)",
        "tags": [
          "AI Admin"
        ]
      }
    },
    "/ai/v2/ingest/web": {
      "post": {
        "operationId": "AiAdminController_ingestWebSecret",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestWebDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ingest website content into the vector store (secret key)",
        "tags": [
          "AI Admin"
        ]
      }
    },
    "/ai/health": {
      "get": {
        "operationId": "AiHealthController_health",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "AI health check (vector store + embeddings + LLM)",
        "tags": [
          "AI Health"
        ]
      }
    },
    "/identify": {
      "post": {
        "operationId": "PublicApiController_identify",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IdentifyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Register a wallet with the workspace (wallet addresses only)",
        "tags": [
          "Public API (server-to-server)"
        ]
      }
    },
    "/contacts": {
      "get": {
        "operationId": "PublicApiController_contacts",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "hasWallet",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List contacts with reachability and tags (no PII returned)",
        "tags": [
          "Public API (server-to-server)"
        ]
      }
    },
    "/campaigns/{id}/send": {
      "post": {
        "operationId": "PublicApiController_sendCampaign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "summary": "Launch a prepared campaign",
        "tags": [
          "Public API (server-to-server)"
        ]
      }
    },
    "/messages/pending": {
      "get": {
        "operationId": "PublicApiController_pending",
        "parameters": [
          {
            "name": "wallet",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Queued in-app pushes for a wallet",
        "tags": [
          "Public API (server-to-server)"
        ]
      }
    },
    "/organization/analytics/overview": {
      "get": {
        "operationId": "OrgAnalyticsController_overview",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Five headline KPIs with period-over-period deltas",
        "tags": [
          "Organization analytics"
        ]
      }
    },
    "/organization/analytics/timeseries": {
      "get": {
        "operationId": "OrgAnalyticsController_timeseries",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "type": "string"
            }
          },
          {
            "name": "metrics",
            "required": false,
            "in": "query",
            "description": "Comma-separated: reach,conversions",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Bucketed series (daily ≤30d, weekly at 90d)",
        "tags": [
          "Organization analytics"
        ]
      }
    },
    "/organization/analytics/push-delivery": {
      "get": {
        "operationId": "OrgAnalyticsController_pushDelivery",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "In-app push funnel: queued → delivered → viewed → clicked",
        "tags": [
          "Organization analytics"
        ]
      }
    },
    "/organization/analytics/onchain": {
      "get": {
        "operationId": "OrgAnalyticsController_onchain",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "On-chain activity: new holders, conversions, retention",
        "tags": [
          "Organization analytics"
        ]
      }
    },
    "/organization/analytics/attribution": {
      "get": {
        "operationId": "OrgAnalyticsController_attribution",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "type": "string"
            }
          },
          {
            "name": "windowHours",
            "required": false,
            "in": "query",
            "description": "Attribution window (default 72, max 720)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Conversions occurring after a message, within the attribution window",
        "tags": [
          "Organization analytics"
        ]
      }
    },
    "/early-access": {
      "post": {
        "operationId": "EarlyAccessController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEarlyAccessDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Public early-access / waitlist signup",
        "tags": [
          "early-access"
        ]
      }
    },
    "/events": {
      "post": {
        "operationId": "EventsController_ingest",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestEventDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Event accepted/queued (idempotent)."
          }
        },
        "summary": "Ingest a custom app event (server-to-server, sk_*)",
        "tags": [
          "Events"
        ]
      }
    },
    "/events/batch": {
      "post": {
        "operationId": "EventsController_ingestBatch",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestEventBatchDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": ""
          }
        },
        "summary": "Batch-ingest custom app events (server-to-server, sk_*)",
        "tags": [
          "Events"
        ]
      }
    },
    "/events/catalog": {
      "get": {
        "operationId": "EventsController_catalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Distinct app-event names (30d) for trigger autocomplete",
        "tags": [
          "Events"
        ]
      }
    },
    "/assets": {
      "post": {
        "operationId": "AssetsController_upload",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Upload an image/font asset (hosted URL returned)",
        "tags": [
          "assets"
        ]
      },
      "get": {
        "operationId": "AssetsController_list",
        "parameters": [
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List org assets (paginated, filter by kind)",
        "tags": [
          "assets"
        ]
      }
    },
    "/assets/{id}": {
      "delete": {
        "operationId": "AssetsController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Delete an org asset",
        "tags": [
          "assets"
        ]
      }
    },
    "/forms": {
      "post": {
        "operationId": "FormsController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Create a capture form (returns embed code + submit URL)",
        "tags": [
          "capture-forms"
        ]
      },
      "get": {
        "operationId": "FormsController_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List capture forms (paginated)",
        "tags": [
          "capture-forms"
        ]
      }
    },
    "/forms/{id}/tag-test-submit": {
      "post": {
        "operationId": "FormsController_tagTestSubmit",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Test submit: apply a form’s tags to a sample submission",
        "tags": [
          "capture-forms"
        ]
      }
    },
    "/forms/{id}": {
      "get": {
        "operationId": "FormsController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get a capture form (with embed code)",
        "tags": [
          "capture-forms"
        ]
      },
      "patch": {
        "operationId": "FormsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Update a capture form",
        "tags": [
          "capture-forms"
        ]
      },
      "delete": {
        "operationId": "FormsController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Delete a capture form",
        "tags": [
          "capture-forms"
        ]
      }
    },
    "/forms/{id}/submissions": {
      "get": {
        "operationId": "FormsController_submissions",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List a form’s submissions (paginated)",
        "tags": [
          "capture-forms"
        ]
      }
    },
    "/forms/{id}/submissions/export.csv": {
      "get": {
        "operationId": "FormsController_exportSubmissions",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Export a form's submissions as CSV",
        "tags": [
          "capture-forms"
        ]
      }
    },
    "/forms/{id}/connect": {
      "post": {
        "operationId": "FormsController_connect",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Connect the form to the API — auto-enables ZK encryption on captures",
        "tags": [
          "capture-forms"
        ]
      }
    },
    "/public/forms/{token}/nonce": {
      "get": {
        "operationId": "FormsPublicController_nonce",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wallet",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "One-time nonce for wallet ownership proof (public)",
        "tags": [
          "capture-forms (public)"
        ]
      }
    },
    "/public/forms/{token}/submit": {
      "post": {
        "operationId": "FormsPublicController_submit",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicSubmitCaptureDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Public capture-form submission (embed / own-site form)",
        "tags": [
          "capture-forms (public)"
        ]
      }
    },
    "/public/forms/confirm/{token}": {
      "get": {
        "operationId": "FormsPublicController_confirm",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Confirm a double opt-in subscription (email link)",
        "tags": [
          "capture-forms (public)"
        ]
      }
    },
    "/public/forms/{token}": {
      "get": {
        "operationId": "FormsPublicController_publicForm",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Public capture-form definition for the hosted page (no PII)",
        "tags": [
          "capture-forms (public)"
        ]
      }
    },
    "/forms/{token}/ingest": {
      "post": {
        "operationId": "FormsApiController_ingest",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "origin",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitCaptureDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Ingest a capture via secret key (auto-connects the form, ZK forced)",
        "tags": [
          "capture-forms (api)"
        ]
      }
    },
    "/rewards/summary": {
      "get": {
        "operationId": "RewardsController_summary",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "History rows (1–100, default 25).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Points balance, tier, lifetime earned, and recent history",
        "tags": [
          "rewards"
        ]
      }
    },
    "/rewards/referrals": {
      "get": {
        "operationId": "RewardsController_referrals",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "The org's referral code and what it has earned",
        "tags": [
          "rewards"
        ]
      }
    },
    "/rewards/notify": {
      "post": {
        "operationId": "RewardsController_notify",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Register interest in the Rewards programme",
        "tags": [
          "rewards"
        ]
      }
    },
    "/developer/keys": {
      "get": {
        "operationId": "DeveloperController_listKeys",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SecretKeyDto"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List secret keys (masked) for the active org",
        "tags": [
          "Developer API"
        ]
      },
      "post": {
        "operationId": "DeveloperController_createKey",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSecretKeyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedSecretKeyDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a secret key — the full token is returned only here",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/developer/keys/{keyId}/roll": {
      "post": {
        "operationId": "DeveloperController_rollKey",
        "parameters": [
          {
            "name": "keyId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollSecretKeyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedSecretKeyDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Roll a secret key — returns the replacement token once and expires the old key",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/developer/keys/{keyId}": {
      "delete": {
        "operationId": "DeveloperController_revokeKey",
        "parameters": [
          {
            "name": "keyId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedKeyDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Revoke a secret key",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/developer/webhooks/events": {
      "get": {
        "operationId": "DeveloperController_listEvents",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEventsDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the subscribable webhook event topics",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/developer/webhooks": {
      "get": {
        "operationId": "DeveloperController_listWebhooks",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpointDto"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List webhook endpoints (signing secret masked)",
        "tags": [
          "Developer API"
        ]
      },
      "post": {
        "operationId": "DeveloperController_createWebhook",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookEndpointDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Register an endpoint (https) — the signing secret is returned only here",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/developer/webhooks/{id}": {
      "patch": {
        "operationId": "DeveloperController_updateWebhook",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pause/resume an endpoint or change its events",
        "tags": [
          "Developer API"
        ]
      },
      "delete": {
        "operationId": "DeveloperController_removeWebhook",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedWebhookDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a webhook endpoint",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/developer/webhooks/{id}/test": {
      "post": {
        "operationId": "DeveloperController_testWebhook",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResultDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send a signed test (`ping`) event to an endpoint",
        "tags": [
          "Developer API"
        ]
      }
    },
    "/help/suggest": {
      "get": {
        "operationId": "HelpController_suggest",
        "parameters": [
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Typeahead help suggestions for the search bar",
        "tags": [
          "Help"
        ]
      }
    },
    "/help/ask": {
      "post": {
        "operationId": "HelpController_ask",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskHelpDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Answer a how-to question from the help corpus",
        "tags": [
          "Help"
        ]
      }
    },
    "/help/articles/{slug}": {
      "get": {
        "operationId": "HelpController_getArticle",
        "parameters": [
          {
            "name": "slug",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a full help article by slug",
        "tags": [
          "Help"
        ]
      }
    }
  },
  "info": {
    "title": "Onchain Suite",
    "description": "API Documentation",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [],
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "GenerateInsightDto": {
        "type": "object",
        "properties": {
          "subTemplate": {
            "type": "string",
            "description": "Optional override sub-template"
          }
        }
      },
      "SegmentConditionDto": {
        "type": "object",
        "properties": {
          "field": {
            "enum": [
              "wallet_balance",
              "last_active",
              "transaction_count",
              "email_opened",
              "token_held",
              "gas_spent"
            ],
            "type": "string",
            "example": "wallet_balance"
          },
          "operator": {
            "enum": [
              "gt",
              "lt",
              "eq",
              "within"
            ],
            "type": "string",
            "example": "gt"
          },
          "value": {
            "type": "object",
            "example": 1000,
            "description": "Numeric threshold. For last_active + within, this is a number of days."
          }
        },
        "required": [
          "field",
          "operator",
          "value"
        ]
      },
      "PreviewSegmentDto": {
        "type": "object",
        "properties": {
          "match": {
            "enum": [
              "AND",
              "OR"
            ],
            "type": "string",
            "example": "AND"
          },
          "conditions": {
            "maxItems": 25,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SegmentConditionDto"
            }
          }
        },
        "required": [
          "match",
          "conditions"
        ]
      },
      "GenerateRulesDto": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 2000,
            "example": "wallets with over $1000 balance active in the last 30 days"
          }
        },
        "required": [
          "prompt"
        ]
      },
      "UpsertAutomationTemplateDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "triggerSpec": {
            "type": "object",
            "additionalProperties": true
          },
          "flowGraph": {
            "type": "object",
            "additionalProperties": true
          },
          "isPublic": {
            "type": "boolean",
            "default": false
          },
          "tier": {
            "type": "string",
            "enum": [
              "starter",
              "advanced"
            ],
            "example": "starter|advanced"
          },
          "recommendedChannels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tierGate": {
            "type": "object",
            "additionalProperties": true
          },
          "copyTemplate": {
            "type": "object",
            "additionalProperties": true
          },
          "recommendedTiming": {
            "type": "object",
            "additionalProperties": true
          },
          "peerBenchmark": {
            "type": "object",
            "additionalProperties": true
          },
          "protocolTypeRelevance": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "schemaVersion": {
            "type": "number",
            "default": 2
          }
        },
        "required": [
          "name",
          "description",
          "triggerSpec",
          "flowGraph"
        ]
      },
      "ApplyTemplateDto": {
        "type": "object",
        "properties": {
          "overrides": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "channels": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "segmentRules": {
                "type": "object"
              }
            },
            "required": []
          }
        }
      },
      "SendEmailDto": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "format": "email",
            "example": "user@example.com",
            "description": "Recipient email address"
          },
          "subject": {
            "type": "string",
            "example": "Welcome!",
            "description": "Email subject"
          },
          "html": {
            "type": "string",
            "example": "<h1>Hello</h1>",
            "description": "HTML content of the email"
          },
          "text": {
            "type": "string",
            "example": "Hello",
            "description": "Plain text content of the email"
          },
          "from": {
            "type": "string",
            "format": "email",
            "example": "sender@verified-domain.com",
            "description": "Sender email address. Must be verified."
          },
          "tags": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "campaign": "onboarding"
            },
            "description": "Tags for SES analytics"
          },
          "configurationSet": {
            "type": "string",
            "example": "my-config-set",
            "description": "SES Configuration Set to use"
          }
        },
        "required": [
          "to",
          "subject",
          "html"
        ]
      },
      "UpdateSendingPolicyDto": {
        "type": "object",
        "properties": {
          "acsTier": {
            "type": "number",
            "enum": [
              100,
              200,
              225,
              250,
              275,
              300,
              310,
              320,
              330,
              340,
              350,
              360
            ],
            "example": 250,
            "description": "Granted ACS tier (100, 200, 225, 250, 275, 300, 310, 320, 330, 340, 350, 360). Denormalizes per-minute/hour ceilings unless given explicitly."
          },
          "maxPerMinute": {
            "type": "number",
            "minimum": 1,
            "example": 1000,
            "description": "Custom per-minute ceiling (overrides the tier default)."
          },
          "maxPerHour": {
            "type": "number",
            "minimum": 1,
            "example": 3000,
            "description": "Custom per-hour ceiling (overrides the tier default)."
          },
          "paused": {
            "type": "boolean",
            "example": false,
            "description": "Hard pause: the worker parks every send for this domain."
          },
          "dailyCapOverride": {
            "type": "number",
            "minimum": 0,
            "example": 5000,
            "description": "Per-day override cap; takes precedence over the warm-up curve. 0 blocks all sends for the day."
          },
          "notes": {
            "type": "string",
            "maxLength": 2000,
            "example": "Tier 250 granted 2026-07-30, case #123",
            "description": "Ticket bookkeeping notes for the quota runbook."
          },
          "lastTierRequested": {
            "type": "number",
            "enum": [
              100,
              200,
              225,
              250,
              275,
              300,
              310,
              320,
              330,
              340,
              350,
              360
            ],
            "example": 300,
            "description": "Tier last requested from Azure (runbook bookkeeping)."
          },
          "provider": {
            "enum": [
              "acs",
              "ses"
            ],
            "type": "string",
            "example": "ses",
            "description": "Outbound email provider for this domain ('acs' default | 'ses'). Platform-admin only: flipping to 'ses' routes sends through AWS SES and surfaces SES DNS records in the domain checklist."
          },
          "ipPool": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[a-zA-Z0-9_-]+$",
            "example": "ocs-enterprise-pool-1",
            "description": "Enterprise override: dedicated SES IP pool (SendingPoolName) for this domain's per-tenant configuration set. Platform-admin only. Empty/absent = env AWS_SES_POOL_BULK or the SES shared pool."
          }
        }
      },
      "CreateDomainDto": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "type": {
            "enum": [
              "OWNED",
              "MANAGED"
            ],
            "type": "string",
            "default": "OWNED"
          }
        },
        "required": [
          "domain"
        ]
      },
      "SetDomainPurposeDto": {
        "type": "object",
        "properties": {
          "purpose": {
            "enum": [
              "transactional",
              "marketing"
            ],
            "type": "string",
            "description": "What this domain is for. 'transactional' routes via Azure ACS; 'marketing' routes via AWS SES."
          }
        },
        "required": [
          "purpose"
        ]
      },
      "AutoDnsDto": {
        "type": "object",
        "properties": {
          "provider": {
            "enum": [
              "godaddy",
              "cloudflare",
              "namecheap",
              "porkbun"
            ],
            "type": "string"
          },
          "credentials": {
            "type": "object",
            "description": "Provider credentials (apiKey/apiSecret for GoDaddy, apiToken/zoneId for Cloudflare, apiKey/username/clientIp for Namecheap, apiKey/secretApiKey for Porkbun)"
          }
        },
        "required": [
          "provider",
          "credentials"
        ]
      },
      "CreateSenderDto": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "description": "The username part of the email (e.g., info)",
            "example": "info"
          },
          "displayName": {
            "type": "string",
            "description": "Display name for the sender",
            "example": "Info Team"
          }
        },
        "required": [
          "username"
        ]
      },
      "CreateSenderIdentityDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "email"
        ]
      },
      "SetDefaultSenderDto": {
        "type": "object",
        "properties": {
          "senderIdentityId": {
            "type": "string"
          }
        },
        "required": [
          "senderIdentityId"
        ]
      },
      "UpdateSmartSendingSettingsDto": {
        "type": "object",
        "properties": {
          "windowHours": {
            "type": "number",
            "minimum": 1,
            "maximum": 168,
            "description": "Suppression window in hours (1–168). Recipients emailed within this window are skipped when smart sending is on.",
            "example": 10
          },
          "enabledByDefault": {
            "type": "boolean",
            "description": "When true, campaigns that never configured tracking behave as if smart sending were enabled."
          }
        },
        "required": [
          "windowHours"
        ]
      },
      "ProjectContractAddressDto": {
        "type": "object",
        "properties": {
          "chain": {
            "type": "string",
            "maxLength": 64,
            "example": "ethereum"
          },
          "address": {
            "type": "string",
            "maxLength": 160,
            "example": "0x1234567890abcdef1234567890abcdef12345678"
          },
          "label": {
            "type": "string",
            "maxLength": 120,
            "example": "Core Token"
          },
          "icon": {
            "type": "string",
            "description": "Optional icon override. When omitted, the API auto-derives an icon from the\nGoldRush token-logo CDN based on the chain + address, so most contracts need\nno manual icon. Set this to pin a custom image (e.g. for testnet/custom\ncontracts the CDN has no logo for).",
            "maxLength": 2048,
            "example": "https://logos.covalenthq.com/tokens/1/0x....png"
          }
        }
      },
      "UpdateProjectSettingsDto": {
        "type": "object",
        "properties": {
          "projectName": {
            "type": "string",
            "maxLength": 120,
            "example": "Goldgard"
          },
          "billingEmail": {
            "type": "string",
            "maxLength": 254,
            "format": "email",
            "example": "billing@acme.com"
          },
          "tokenTicker": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._-]{2,20}$",
            "example": "SUITE"
          },
          "primaryChains": {
            "maxItems": 20,
            "example": [
              "ethereum",
              "base"
            ],
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            }
          },
          "phone": {
            "type": "string",
            "pattern": "^\\+[1-9]\\d{1,14}$",
            "example": "+1234567890"
          },
          "taxId": {
            "type": "string",
            "maxLength": 120,
            "example": "US-123456789"
          },
          "timezone": {
            "type": "string",
            "maxLength": 100,
            "example": "UTC"
          },
          "address": {
            "type": "string",
            "maxLength": 500,
            "example": "123 Market St, San Francisco, CA 94103"
          },
          "contractAddresses": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectContractAddressDto"
            }
          }
        }
      },
      "UpdateOrganizationDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "website": {
            "type": "string"
          },
          "subdomain": {
            "type": "string"
          },
          "landingPage": {
            "type": "string"
          },
          "branding": {
            "type": "object"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Arbitrary organization metadata (merged into existing Organization.metadata JSON)."
          },
          "settings": {
            "type": "object",
            "additionalProperties": true,
            "description": "Convenience alias merged into metadata.settings (for account/project settings forms)."
          },
          "projectSettings": {
            "description": "Typed project settings merged into metadata.projectSettings and mirrored into metadata.project/settings.",
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdateProjectSettingsDto"
              }
            ]
          }
        }
      },
      "ValidateSubdomainDto": {
        "type": "object",
        "properties": {
          "subdomain": {
            "type": "string",
            "pattern": "^[a-z0-9-]+$"
          }
        },
        "required": [
          "subdomain"
        ]
      },
      "UpdateColorsDto": {
        "type": "object",
        "properties": {
          "primary": {
            "type": "string",
            "pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
          },
          "secondary": {
            "type": "string"
          },
          "accent": {
            "type": "string"
          }
        },
        "required": [
          "primary"
        ]
      },
      "UpdateEmailBuilderBrandingDto": {
        "type": "object",
        "properties": {
          "primaryColor": {
            "type": "string",
            "pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",
            "description": "Primary brand color used by the email builder.",
            "example": "#10b981"
          },
          "secondaryColor": {
            "type": "string",
            "pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",
            "description": "Secondary brand color used by the email builder.",
            "example": "#6366f1"
          },
          "accentColor": {
            "type": "string",
            "pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",
            "description": "Optional accent color used by the email builder.",
            "example": "#f59e0b"
          },
          "headingFont": {
            "type": "string",
            "pattern": "^[\\w\\s,\"'-]{1,100}$",
            "description": "Preferred heading font family for email builder content.",
            "example": "Inter"
          },
          "bodyFont": {
            "type": "string",
            "pattern": "^[\\w\\s,\"'-]{1,100}$",
            "description": "Preferred body font family for email builder content.",
            "example": "Inter"
          }
        }
      },
      "UpdateMemberDto": {
        "type": "object",
        "properties": {
          "role": {
            "enum": [
              "OWNER",
              "ADMIN",
              "EDITOR",
              "VIEWER"
            ],
            "type": "string",
            "description": "The role of the member in the organization",
            "example": "ADMIN"
          },
          "isEnabled": {
            "type": "boolean",
            "description": "Whether the member is enabled or disabled",
            "example": true
          }
        }
      },
      "InviteMemberDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email address of the user to invite",
            "example": "colleague@example.com"
          },
          "role": {
            "enum": [
              "OWNER",
              "ADMIN",
              "EDITOR",
              "VIEWER"
            ],
            "type": "string",
            "description": "Role to assign to the invited user",
            "example": "EDITOR"
          }
        },
        "required": [
          "email",
          "role"
        ]
      },
      "SignUpDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "johndoe@example.com"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "example": "password123"
          },
          "name": {
            "type": "string",
            "example": "John Doe"
          },
          "username": {
            "type": "string",
            "example": "johndoe"
          },
          "firstName": {
            "type": "string",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "isOrgEmail": {
            "type": "boolean",
            "example": true
          },
          "orgName": {
            "type": "string",
            "example": "My Company"
          }
        },
        "required": [
          "email",
          "password",
          "name"
        ]
      },
      "SignInDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "johndoe@example.com"
          },
          "username": {
            "type": "string",
            "example": "johndoe"
          },
          "password": {
            "type": "string",
            "example": "password123"
          }
        },
        "required": [
          "password"
        ]
      },
      "ForgotPasswordDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "user@example.com",
            "description": "User email address"
          }
        },
        "required": [
          "email"
        ]
      },
      "ResendVerificationDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "user@example.com",
            "description": "Email address of the account to resend the verification link to"
          }
        },
        "required": [
          "email"
        ]
      },
      "ResetPasswordDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "The reset token received via email"
          },
          "newPassword": {
            "type": "string",
            "minLength": 8,
            "pattern": "((?=.*\\d)|(?=.*\\W+))(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$",
            "example": "NewPassword123!",
            "description": "New password"
          }
        },
        "required": [
          "token",
          "newPassword"
        ]
      },
      "CreateCampaignDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable campaign name shown in lists and the editor."
          },
          "type": {
            "type": "string",
            "description": "Campaign type: EMAIL_BLAST (default) or SMART_SENDING."
          },
          "subject": {
            "type": "string"
          },
          "htmlContent": {
            "type": "string",
            "description": "Initial HTML body; stored under the campaign `content.html` field."
          },
          "recipients": {
            "type": "object",
            "description": "Initial audience selection (profile/segment IDs or raw email list)."
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateCampaignAudienceDto": {
        "type": "object",
        "properties": {
          "profileIds": {
            "description": "Canonical audience profile/contact IDs selected from GET /audience/profiles.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "segmentIds": {
            "description": "Intelligence segment IDs selected from GET /intelligence/segments.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "all": {
            "type": "boolean",
            "description": "Send to ALL contacts in the organization. Mutually exclusive with profileIds/segmentIds; when true they are ignored."
          }
        }
      },
      "UpdateCampaignTrackingDto": {
        "type": "object",
        "properties": {
          "smartSending": {
            "type": "boolean",
            "description": "Enable or disable smart sending behavior."
          },
          "trackingParameters": {
            "type": "boolean",
            "description": "Enable or disable tracking parameter injection."
          },
          "openTracking": {
            "type": "boolean",
            "description": "Enable or disable open tracking. Defaults to true when omitted."
          },
          "clickTracking": {
            "type": "boolean",
            "description": "Enable or disable click tracking. Defaults to true when omitted."
          },
          "smartSendingWindowHours": {
            "type": "number",
            "minimum": 1,
            "maximum": 168,
            "description": "Per-campaign smart-sending suppression window override in hours (1–168). When omitted, the org-wide setting (PUT /organization/settings/smart-sending) applies, then the platform default (10h)."
          },
          "utm": {
            "type": "object",
            "additionalProperties": true,
            "description": "Optional UTM/tracking metadata persisted with the campaign."
          }
        },
        "required": [
          "smartSending",
          "trackingParameters"
        ]
      },
      "RequeueUnsentDto": {
        "type": "object",
        "properties": {
          "addresses": {
            "minItems": 1,
            "maxItems": 5000,
            "description": "Recipients to re-send. OMIT to derive the unsent set from the database (launch recipients with no delivered/bounced/failed event, joined on recipient_hmac) — that is the normal path. Supply a list only to override the telemetry. Each address must belong to a launch send on this campaign; test-send rows and unknown addresses are reported, never mailed. NOTE an empty array means \"these zero people\" and is a no-op, which is deliberately NOT the same as omitting the field.",
            "example": [
              "kris@yauga.com",
              "sj2389@hotmail.co.uk"
            ],
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "dryRun": {
            "type": "boolean",
            "description": "Report what would be sent, and which addresses are not part of this campaign, without enqueuing. Run this first.",
            "default": false
          },
          "chunkSize": {
            "type": "number",
            "minimum": 1,
            "maximum": 2000,
            "description": "Recipients enqueued per batch, so one call cannot dump the whole audience into Redis at once.",
            "default": 500
          }
        }
      },
      "PushCredentialDto": {
        "type": "object",
        "properties": {
          "provider": {
            "enum": [
              "apns",
              "fcm"
            ],
            "type": "string",
            "example": "apns"
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Non-secret identifiers, safe to render (keyId, teamId, …).",
            "example": {
              "keyId": "ABC123",
              "teamId": "TEAM456",
              "bundleId": "com.acme.app"
            }
          },
          "fingerprint": {
            "type": "string",
            "example": "a1b2c3d4",
            "description": "Short hash identifying WHICH key is installed, not the key."
          },
          "verified": {
            "type": "boolean",
            "description": "Whether the credential verified with the vendor."
          },
          "verifiedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "lastError": {
            "type": "string",
            "nullable": true,
            "description": "Why verification failed, when it did."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "provider",
          "config",
          "fingerprint",
          "verified",
          "verifiedAt",
          "lastError",
          "updatedAt"
        ]
      },
      "PushCredentialListDto": {
        "type": "object",
        "properties": {
          "credentials": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PushCredentialDto"
            }
          }
        },
        "required": [
          "credentials"
        ]
      },
      "RemovedCountDto": {
        "type": "object",
        "properties": {
          "removed": {
            "type": "number",
            "example": 1,
            "description": "Number of records removed."
          }
        },
        "required": [
          "removed"
        ]
      },
      "VapidKeyDto": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "False when web push is not configured — the SDK skips the prompt."
          },
          "publicKey": {
            "type": "string",
            "nullable": true,
            "description": "VAPID public key, or null when web push is unconfigured."
          }
        },
        "required": [
          "enabled",
          "publicKey"
        ]
      },
      "PushRegisteredDto": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "boolean",
            "example": true
          },
          "id": {
            "type": "string",
            "description": "Subscription id."
          },
          "kind": {
            "type": "string",
            "example": "web",
            "description": "Registration kind: `web`, `ios`, or `android`."
          }
        },
        "required": [
          "registered",
          "id",
          "kind"
        ]
      },
      "InappChallengeDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "maxLength": 64,
            "example": "0xabc..."
          }
        },
        "required": [
          "walletAddress"
        ]
      },
      "InappChallengeResponseDto": {
        "type": "object",
        "properties": {
          "nonceId": {
            "type": "string",
            "description": "Opaque id tying the signature back to this nonce."
          },
          "message": {
            "type": "string",
            "description": "The exact message the wallet must sign."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the challenge expires."
          }
        },
        "required": [
          "nonceId",
          "message",
          "expiresAt"
        ]
      },
      "InappVerifyDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "maxLength": 64,
            "example": "0xabc..."
          },
          "signature": {
            "type": "string",
            "maxLength": 255,
            "description": "EIP-191 (EVM) or base58 (SVM) signature over the issued message"
          }
        },
        "required": [
          "walletAddress",
          "signature"
        ]
      },
      "InappSessionDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "In-app session token (bearer for push + socket)."
          },
          "wsUrl": {
            "type": "string",
            "description": "WebSocket URL to connect the in-app inbox to."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "token",
          "wsUrl",
          "expiresAt"
        ]
      },
      "AddAllowedOriginDto": {
        "type": "object",
        "properties": {
          "origin": {
            "type": "string",
            "example": "https://app.example.com"
          },
          "environment": {
            "enum": [
              "production",
              "staging",
              "development"
            ],
            "type": "string",
            "example": "production"
          }
        },
        "required": [
          "origin",
          "environment"
        ]
      },
      "InappTestPushDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "example": "0xabc..."
          },
          "title": {
            "type": "string",
            "example": "Welcome"
          },
          "body": {
            "type": "string",
            "example": "Thanks for joining…"
          },
          "ctaLabel": {
            "type": "string",
            "example": "Open app"
          },
          "ctaUrl": {
            "type": "string",
            "example": "https://app.example.com/path"
          }
        },
        "required": [
          "walletAddress",
          "title",
          "body"
        ]
      },
      "InappProtocolPushDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "example": "0xabc..."
          },
          "title": {
            "type": "string",
            "example": "Welcome"
          },
          "body": {
            "type": "string",
            "example": "Thanks for joining…"
          },
          "templateId": {
            "type": "string",
            "example": "tmpl_123",
            "description": "Org-library in-app template to send (content.channel = \"inapp\"). Inline title/body/cta override the template."
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "reward": "120 USDC"
            },
            "description": "Values substituted into {{ var }} tokens in the content. wallet, wallet_address, and wallet_short are auto-provided."
          },
          "automationId": {
            "type": "string",
            "example": "inapp_test"
          },
          "ctaLabel": {
            "type": "string",
            "example": "Open app"
          },
          "ctaUrl": {
            "type": "string",
            "example": "https://app.example.com/path"
          }
        },
        "required": [
          "walletAddress"
        ]
      },
      "CreateSecretKeyDto": {
        "type": "object",
        "properties": {
          "environment": {
            "enum": [
              "live",
              "test"
            ],
            "type": "string",
            "example": "test"
          },
          "name": {
            "type": "string",
            "example": "Prod server key"
          },
          "scope": {
            "description": "Permission scope. `read_write` (default) can call mutating S2S routes;\n`read_only` is rejected by them with a 403. Independent of `environment`.",
            "enum": [
              "read_write",
              "read_only"
            ],
            "type": "string",
            "default": "read_write"
          }
        },
        "required": [
          "environment"
        ]
      },
      "RelayMetricsDto": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "maxLength": 5000000,
            "description": "Prometheus exposition-format payload from the queue worker."
          }
        },
        "required": [
          "text"
        ]
      },
      "PurgeQueueDto": {
        "type": "object",
        "properties": {
          "confirm": {
            "type": "string",
            "description": "Must exactly equal the queue name in the URL. Guards against a mistyped or copy-pasted request hitting the wrong queue.",
            "example": "email"
          },
          "mode": {
            "enum": [
              "clean",
              "obliterate"
            ],
            "type": "string",
            "default": "clean",
            "description": "'clean' removes jobs in the given states and leaves queue structures intact (default). 'obliterate' destroys ALL queue data including active jobs — irreversible."
          },
          "states": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "wait",
                "delayed",
                "failed",
                "completed"
              ]
            },
            "description": "States to clean. Defaults to ['wait','delayed'] — the parked backlog — deliberately NOT 'active', which would orphan jobs mid-send."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 1000000,
            "default": 100000,
            "description": "Maximum jobs to remove per state in one call."
          },
          "grace": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Only remove jobs older than this many milliseconds. 0 means all ages."
          }
        },
        "required": [
          "confirm"
        ]
      },
      "UpdateProfileDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "companyName": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "notificationPreferences": {
            "type": "object"
          },
          "preferences": {
            "type": "object"
          }
        }
      },
      "ChangeEmailDto": {
        "type": "object",
        "properties": {
          "newEmail": {
            "type": "string",
            "format": "email"
          }
        },
        "required": [
          "newEmail"
        ]
      },
      "VerifyEmailDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          }
        },
        "required": [
          "token"
        ]
      },
      "ChangePasswordDto": {
        "type": "object",
        "properties": {
          "currentPassword": {
            "type": "string"
          },
          "newPassword": {
            "type": "string",
            "minLength": 8
          }
        },
        "required": [
          "currentPassword",
          "newPassword"
        ]
      },
      "Toggle2faDto": {
        "type": "object",
        "properties": {
          "enable": {
            "type": "boolean"
          }
        },
        "required": [
          "enable"
        ]
      },
      "Verify2faDto": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          }
        },
        "required": [
          "code"
        ]
      },
      "UpdatePreferencesDto": {
        "type": "object",
        "properties": {
          "emailPreferences": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            }
          }
        }
      },
      "CreateContactDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "walletAddress": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "format": "json"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "email"
        ]
      },
      "UpdateContactDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "walletAddress": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "format": "json"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "score": {
            "type": "number"
          }
        }
      },
      "CreateTagDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "pattern": "^#?([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$"
          }
        },
        "required": [
          "name"
        ]
      },
      "ExportFiltersDto": {
        "type": "object",
        "properties": {
          "q": {
            "type": "string"
          },
          "tagsAny": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tagsAll": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdFrom": {
            "type": "string"
          },
          "createdTo": {
            "type": "string"
          }
        }
      },
      "ExportSortDto": {
        "type": "object",
        "properties": {
          "by": {
            "enum": [
              "createdAt",
              "email",
              "name"
            ],
            "type": "string"
          },
          "direction": {
            "enum": [
              "asc",
              "desc"
            ],
            "type": "string"
          }
        }
      },
      "CreateAudienceExportJobDto": {
        "type": "object",
        "properties": {
          "format": {
            "enum": [
              "csv",
              "json"
            ],
            "type": "string"
          },
          "filters": {
            "$ref": "#/components/schemas/ExportFiltersDto"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "includeAttributes": {
            "type": "boolean"
          },
          "includeTags": {
            "type": "boolean"
          },
          "sort": {
            "$ref": "#/components/schemas/ExportSortDto"
          }
        },
        "required": [
          "format"
        ]
      },
      "CreateImportUploadUrlDto": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string",
            "description": "Original filename (used only to infer an extension when `ext` is absent).",
            "maxLength": 255,
            "example": "subscribers-export.csv"
          },
          "contentType": {
            "type": "string",
            "description": "Intended content type (advisory; the upload PUT sets the real header).",
            "maxLength": 255,
            "example": "text/csv"
          },
          "ext": {
            "type": "string",
            "description": "Explicit extension for the stored blob (e.g. `csv`, `json`, `ndjson`).",
            "maxLength": 16,
            "example": "csv"
          }
        }
      },
      "CreateBlobImportDto": {
        "type": "object",
        "properties": {
          "blobPath": {
            "type": "string",
            "description": "Storage path returned by `POST /audience/imports/upload-url`. Required for\nthe JSON (SAS-upload) form of this endpoint.",
            "maxLength": 1024,
            "example": "imports/org_123/6f1b...e2.csv"
          },
          "format": {
            "description": "Override the inferred format. Otherwise derived from the blob extension.",
            "enum": [
              "csv",
              "json"
            ],
            "type": "string"
          },
          "contentType": {
            "type": "string",
            "description": "Content type recorded on the synthesized file (defaults to `text/csv`).",
            "maxLength": 255,
            "example": "text/csv"
          },
          "mode": {
            "description": "Import write mode.",
            "enum": [
              "upsert",
              "create_only",
              "update_only"
            ],
            "type": "string"
          },
          "onConflict": {
            "description": "Conflict resolution when a match already exists.",
            "enum": [
              "skip",
              "update"
            ],
            "type": "string"
          },
          "dedupeKey": {
            "description": "Which field identifies a duplicate contact.",
            "enum": [
              "email",
              "walletAddress"
            ],
            "type": "string"
          },
          "dryRun": {
            "type": "boolean",
            "description": "Validate-only run: parse and report counts without writing contacts.",
            "example": false
          },
          "platform": {
            "type": "string",
            "description": "Apply a known platform's export-header preset (e.g. `mailchimp`).",
            "maxLength": 64,
            "example": "mailchimp"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone for interpreting date columns.",
            "maxLength": 64,
            "example": "UTC"
          },
          "maxErrors": {
            "type": "number",
            "description": "Abort the job after this many row errors.",
            "minimum": 0,
            "maximum": 1000000,
            "example": 1000
          },
          "zk": {
            "type": "boolean",
            "description": "Force ZK protection on imported contacts.",
            "example": false
          }
        }
      },
      "CreateSuppressionDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email address to suppress"
          }
        },
        "required": [
          "email"
        ]
      },
      "CardSetupIntentDto": {
        "type": "object",
        "properties": {
          "organizationId": {
            "type": "string",
            "description": "Falls back to the x-org-id header when omitted."
          },
          "successUrl": {
            "type": "string",
            "description": "Stripe's success_url. Defaults to the billing tab."
          },
          "cancelUrl": {
            "type": "string",
            "description": "Stripe's cancel_url. Defaults to the billing tab."
          }
        }
      },
      "Object": {
        "type": "object",
        "properties": {}
      },
      "CreateUpgradeCheckoutDto": {
        "type": "object",
        "properties": {
          "desiredListSize": {
            "type": "number",
            "minimum": 1
          },
          "plan": {
            "type": "string"
          }
        },
        "required": [
          "desiredListSize"
        ]
      },
      "CreatePlanCheckoutDto": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "string",
            "description": "Plan key (launch | growth | pro; case-insensitive, aliases accepted) or a billing_plans row id as returned by GET /billing/plans."
          },
          "organizationId": {
            "type": "string"
          },
          "billingCycle": {
            "type": "string",
            "description": "monthly (default) | annual"
          },
          "contacts": {
            "type": "number",
            "description": "Contact capacity to purchase (pricing slider). Priced by the same curve as GET /billing/contact-pricing. Ignored when <= the tier limit.",
            "minimum": 0,
            "maximum": 10000000,
            "example": 11000
          },
          "extraSeats": {
            "type": "number",
            "description": "Seats to purchase above the tier's included count, priced at the rate card's per-seat rate.",
            "minimum": 0,
            "maximum": 50,
            "example": 2
          },
          "blockchain": {
            "type": "string",
            "description": "Payment chain for crypto checkout (base | ethereum | solana | polygon | bnb | optimism). Default: base."
          },
          "paymentMethod": {
            "type": "string",
            "enum": [
              "crypto",
              "card"
            ],
            "description": "'card' (default, Stripe-hosted checkout) or 'crypto' (Blockradar deposit). When omitted and Stripe is unconfigured, falls back to crypto."
          },
          "asset": {
            "enum": [
              "usdc",
              "usdt"
            ],
            "type": "string",
            "description": "Stablecoin the buyer will pay with on the crypto path: 'usdc' (default) or 'usdt'. Both settle 1:1 in USD — this selects labeling only, not the amount."
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "email",
                "in_app"
              ]
            },
            "description": "Channels the buyer is enabling. The plan charge = the SUM of the selected channels' prices (v2 cumulative pricing, e.g. Growth email + in-app = 199 + 149 = 348). Omit (or send empty) for the back-compat single price (email channel only) — identical to today's behavior."
          }
        },
        "required": [
          "plan",
          "organizationId"
        ]
      },
      "CreateCreditTopupDto": {
        "type": "object",
        "properties": {
          "organizationId": {
            "type": "string"
          },
          "amountUsd": {
            "type": "number",
            "minimum": 1,
            "description": "Top-up amount in USD (e.g. 25)"
          },
          "paymentMethod": {
            "type": "string",
            "enum": [
              "crypto",
              "card"
            ],
            "description": "'card' (default, Stripe-hosted checkout) or 'crypto' (Blockradar). When omitted and Stripe is unconfigured, falls back to crypto."
          },
          "asset": {
            "enum": [
              "usdc",
              "usdt"
            ],
            "type": "string",
            "description": "Stablecoin the buyer will pay with on the crypto path: 'usdc' (default) or 'usdt'. Both settle 1:1 in USD — this selects labeling only, not the amount."
          }
        },
        "required": [
          "organizationId",
          "amountUsd"
        ]
      },
      "ToggleAutoOptimizeDto": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ]
      },
      "ChangePlanDto": {
        "type": "object",
        "properties": {
          "planId": {
            "type": "string"
          }
        },
        "required": [
          "planId"
        ]
      },
      "CreatePaymentMethodDto": {
        "type": "object",
        "properties": {
          "type": {
            "enum": [
              "card",
              "crypto"
            ],
            "type": "string"
          },
          "last4": {
            "type": "string",
            "example": "4242"
          },
          "brand": {
            "type": "string",
            "example": "Visa"
          },
          "address": {
            "type": "string",
            "example": "0xabc..."
          },
          "isDefault": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "type"
        ]
      },
      "SetDefaultPaymentMethodDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "UpdatePaymentMethodDto": {
        "type": "object",
        "properties": {
          "paymentMethodId": {
            "type": "string"
          }
        },
        "required": [
          "paymentMethodId"
        ]
      },
      "CompleteOnboardingTaskDto": {
        "type": "object",
        "properties": {
          "contracts": {
            "description": "Contracts to index when completing connect-chain task (array of contract descriptors).",
            "example": [
              {
                "chainId": 1,
                "address": "0x..."
              }
            ],
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "lookbackDays": {
            "type": "number",
            "example": 90
          }
        }
      },
      "TrackOnboardingDto": {
        "type": "object",
        "properties": {
          "stepName": {
            "type": "string",
            "example": "connect_wallet"
          },
          "action": {
            "enum": [
              "started",
              "completed",
              "skipped"
            ],
            "type": "string",
            "example": "started"
          },
          "timeSpentSeconds": {
            "type": "number",
            "minimum": 0,
            "example": 12
          },
          "currentStep": {
            "type": "string",
            "example": "connect_wallet"
          },
          "stepData": {
            "type": "object",
            "additionalProperties": true,
            "example": {
              "chain": "ethereum"
            }
          },
          "flowVersion": {
            "type": "string",
            "example": "v1"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "example": {
              "referrer": "campaign"
            }
          }
        },
        "required": [
          "stepName",
          "action"
        ]
      },
      "CompleteOnboardingDto": {
        "type": "object",
        "properties": {
          "totalTimeSeconds": {
            "type": "number",
            "minimum": 0,
            "example": 123
          },
          "currentStep": {
            "type": "string",
            "example": "completed"
          },
          "stepData": {
            "type": "object",
            "additionalProperties": true,
            "example": {
              "completedBy": "user"
            }
          },
          "flowVersion": {
            "type": "string",
            "example": "v1"
          }
        }
      },
      "RegisterIdentityDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "example": "0xabc..."
          },
          "commitment": {
            "type": "string",
            "description": "Semaphore identity commitment (decimal string) derived client-side from the user identity.",
            "example": "21663839004416932945382355908790599225266501822907911457"
          },
          "bindingSignature": {
            "type": "string",
            "description": "EIP-191 personal_sign of `Bind wallet ${walletAddress} to identity ${commitment}`.",
            "example": "0x..."
          }
        },
        "required": [
          "walletAddress",
          "commitment",
          "bindingSignature"
        ]
      },
      "IssueIdentityOtpDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "example": "0xabc... or wallet identifier"
          },
          "channelType": {
            "enum": [
              "INAPP",
              "EMAIL",
              "TELEGRAM",
              "X",
              "FARCASTER",
              "DISCORD"
            ],
            "type": "string",
            "example": "EMAIL"
          },
          "destination": {
            "type": "string",
            "description": "Email address / handle to receive OTP (channel-dependent)"
          }
        },
        "required": [
          "walletAddress",
          "channelType"
        ]
      },
      "BindIdentityDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "example": "0xabc... or wallet identifier"
          },
          "channelType": {
            "enum": [
              "INAPP",
              "EMAIL",
              "TELEGRAM",
              "X",
              "FARCASTER",
              "DISCORD"
            ],
            "type": "string",
            "example": "EMAIL"
          },
          "value": {
            "type": "string",
            "description": "Plaintext channel value (canonical mode). Backend computes Poseidon-hash + envelope-encrypts.",
            "example": "alice@example.com"
          },
          "valueHash": {
            "type": "string",
            "description": "Client-provided channel value hash (advanced mode).",
            "example": "0x..."
          },
          "encryptedValue": {
            "type": "object",
            "properties": {
              "ciphertext": {
                "type": "string"
              },
              "iv": {
                "type": "string"
              },
              "authTag": {
                "type": "string"
              },
              "wrappedKey": {
                "type": "string"
              },
              "wrapIv": {
                "type": "string"
              },
              "wrapTag": {
                "type": "string"
              },
              "keyVersion": {
                "type": "number"
              }
            },
            "required": [
              "ciphertext",
              "iv",
              "authTag",
              "wrappedKey",
              "wrapIv",
              "wrapTag",
              "keyVersion"
            ]
          },
          "otp": {
            "type": "string",
            "description": "One-time verification code",
            "example": "123456"
          },
          "identityCommitment": {
            "type": "string",
            "description": "Required when ZK identity binding is enforced. Semaphore identity commitment as a decimal string."
          },
          "semaphoreProof": {
            "type": "object",
            "properties": {
              "merkleTreeDepth": {
                "type": "number"
              },
              "merkleTreeRoot": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "nullifier": {
                "type": "string"
              },
              "scope": {
                "type": "string"
              },
              "points": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "merkleTreeDepth",
              "merkleTreeRoot",
              "message",
              "nullifier",
              "scope",
              "points"
            ]
          },
          "source": {
            "type": "string",
            "description": "Optional source metadata",
            "example": "otp"
          }
        },
        "required": [
          "walletAddress",
          "channelType"
        ]
      },
      "DecryptIdentityDto": {
        "type": "object",
        "properties": {
          "commitment": {
            "type": "string",
            "description": "Commitment (decimal string)",
            "example": "2166383900..."
          },
          "channelType": {
            "enum": [
              "INAPP",
              "EMAIL",
              "TELEGRAM",
              "X",
              "FARCASTER",
              "DISCORD"
            ],
            "type": "string",
            "example": "EMAIL"
          }
        },
        "required": [
          "commitment",
          "channelType"
        ]
      },
      "CreateIndexingJobDto": {
        "type": "object",
        "properties": {
          "contracts": {
            "type": "object",
            "example": [
              {
                "chain": "ethereum",
                "contract": "0x..."
              }
            ]
          },
          "lookbackDays": {
            "type": "number",
            "minimum": 1,
            "example": 90
          }
        },
        "required": [
          "contracts"
        ]
      },
      "QueryTextDto": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          },
          "mode": {
            "type": "string",
            "enum": [
              "fast",
              "best"
            ]
          }
        },
        "required": [
          "query"
        ]
      },
      "QueryVoiceDto": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          },
          "mode": {
            "type": "string",
            "enum": [
              "fast",
              "best"
            ]
          }
        },
        "required": [
          "text"
        ]
      },
      "AiFeedbackDto": {
        "type": "object",
        "properties": {
          "queryLogId": {
            "type": "string"
          },
          "rating": {
            "type": "number",
            "minimum": 1,
            "maximum": 5
          },
          "comment": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "rating"
        ]
      },
      "IngestWebDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "maxPages": {
            "type": "number",
            "minimum": 1,
            "maximum": 200
          },
          "maxDepth": {
            "type": "number",
            "minimum": 0,
            "maximum": 5
          },
          "rateLimitMs": {
            "type": "number",
            "minimum": 50,
            "maximum": 5000
          },
          "sourceLabel": {
            "type": "string",
            "maxLength": 200
          },
          "render": {
            "type": "boolean"
          }
        },
        "required": [
          "url"
        ]
      },
      "IdentifyDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "description": "Wallet address — EVM (`0x`+40 hex) or Solana/SVM (base58). Normalized on write.",
            "pattern": "^(0x[a-fA-F0-9]{40}|[1-9A-HJ-NP-Za-km-z]{32,44})$",
            "example": "0x1234567890abcdef1234567890abcdef12345678"
          },
          "ensName": {
            "type": "string",
            "description": "ENS name, if the caller already resolved one. Optional and purely a display\nconvenience — it is public on-chain data, not a personal identifier.",
            "maxLength": 255,
            "example": "vitalik.eth"
          }
        },
        "required": [
          "walletAddress"
        ]
      },
      "CreateEarlyAccessDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "description": "Signup email. Required; normalized (trim + lowercase) before persistence.",
            "maxLength": 320,
            "format": "email"
          },
          "name": {
            "type": "string",
            "description": "Person's name.",
            "maxLength": 200
          },
          "protocol": {
            "type": "string",
            "description": "Protocol / company they represent.",
            "maxLength": 200
          },
          "reasons": {
            "description": "Multi-select reasons for interest (e.g. \"Churn win-back\").",
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 200
            }
          },
          "notes": {
            "type": "string",
            "description": "Free-text notes.",
            "maxLength": 2000
          },
          "source": {
            "type": "string",
            "description": "Which surface the signup came from.",
            "enum": [
              "hero",
              "early-access"
            ]
          }
        },
        "required": [
          "email"
        ]
      },
      "EventContactDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "description": "Email identifier — goes through the PII layer (blind index + encrypt).",
            "maxLength": 320,
            "format": "email"
          },
          "walletAddress": {
            "type": "string",
            "description": "Wallet identifier — public, wallet-first (any chain's address format).",
            "maxLength": 128
          },
          "externalId": {
            "type": "string",
            "description": "The customer's own user id.",
            "maxLength": 128
          }
        }
      },
      "IngestEventDto": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "description": "Event name; lowercased server-side.",
            "pattern": "^[a-zA-Z0-9_.:-]{1,64}$"
          },
          "contact": {
            "$ref": "#/components/schemas/EventContactDto"
          },
          "attributes": {
            "type": "object",
            "additionalProperties": true,
            "description": "Flat contact attributes to merge (≤50 keys; primitive values)."
          },
          "payload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Free-form event data for templates/conditions (≤16 KB serialized)."
          },
          "idempotencyKey": {
            "type": "string",
            "description": "Dedup key; defaults to hash(event+contact+occurredAt).",
            "maxLength": 256
          },
          "occurredAt": {
            "type": "string",
            "description": "Defaults to now; rejected if >7 days old or >5 min in the future."
          },
          "test": {
            "type": "boolean",
            "description": "Dry-run: matched automations are counted/logged, nothing sends."
          }
        },
        "required": [
          "event",
          "contact"
        ]
      },
      "IngestEventBatchDto": {
        "type": "object",
        "properties": {
          "events": {
            "minItems": 1,
            "maxItems": 100,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IngestEventDto"
            }
          }
        },
        "required": [
          "events"
        ]
      },
      "SubmitWalletDto": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128
          },
          "signature": {
            "type": "string",
            "maxLength": 1024
          },
          "nonce": {
            "type": "string",
            "maxLength": 256
          }
        }
      },
      "PublicSubmitCaptureDto": {
        "type": "object",
        "properties": {
          "hp": {
            "type": "string",
            "description": "Honeypot: must stay empty. Any value ⇒ treat as bot.",
            "maxLength": 256
          },
          "turnstileToken": {
            "type": "string",
            "description": "Cloudflare Turnstile token from the widget (`cf-turnstile-response`).",
            "maxLength": 4096
          },
          "wallet": {
            "description": "Nested wallet proof. Takes precedence over the flat `walletAddress` when\nboth are present; the flat field stays supported for the embed script and\nexisting integrations.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SubmitWalletDto"
              }
            ]
          },
          "channels": {
            "type": "object",
            "additionalProperties": true,
            "description": "Social handles captured alongside the address (e.g. `{ x: \"@handle\" }`).\nDeclared for the same reason as `wallet`: undeclared it is stripped, and\nthe capture silently loses everything the visitor typed into those fields."
          },
          "email": {
            "type": "string",
            "description": "Subscriber email; goes through the PII layer (blind index + encrypt).",
            "maxLength": 320,
            "format": "email"
          },
          "walletAddress": {
            "type": "string",
            "description": "Wallet address (any chain). Charset-restricted so it can't carry HTML/script\ninto stored records; broad enough for hex (0x…), base58 (Solana), bech32, and\nCAIP-10 (`chain:address`) forms.",
            "maxLength": 128,
            "pattern": "^[a-zA-Z0-9:._-]+$"
          },
          "fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "Form-defined extra field values; bounded/sanitized server-side."
          },
          "consent": {
            "type": "boolean",
            "description": "GDPR opt-in flag. Required (must be `true`) when the form has\n`requireConsent`; recorded as lawful-basis proof alongside the IP + time."
          },
          "consentText": {
            "type": "string",
            "description": "The exact consent wording the subscriber agreed to. Stored verbatim as the\nproof snapshot; defaults to the form's configured `consentText` when omitted.",
            "maxLength": 2000
          }
        }
      },
      "SubmitCaptureDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "description": "Subscriber email; goes through the PII layer (blind index + encrypt).",
            "maxLength": 320,
            "format": "email"
          },
          "walletAddress": {
            "type": "string",
            "description": "Wallet address (any chain). Charset-restricted so it can't carry HTML/script\ninto stored records; broad enough for hex (0x…), base58 (Solana), bech32, and\nCAIP-10 (`chain:address`) forms.",
            "maxLength": 128,
            "pattern": "^[a-zA-Z0-9:._-]+$"
          },
          "fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "Form-defined extra field values; bounded/sanitized server-side."
          },
          "consent": {
            "type": "boolean",
            "description": "GDPR opt-in flag. Required (must be `true`) when the form has\n`requireConsent`; recorded as lawful-basis proof alongside the IP + time."
          },
          "consentText": {
            "type": "string",
            "description": "The exact consent wording the subscriber agreed to. Stored verbatim as the\nproof snapshot; defaults to the form's configured `consentText` when omitted.",
            "maxLength": 2000
          }
        }
      },
      "SecretKeyDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "k1a2b3c4d5"
          },
          "environment": {
            "enum": [
              "live",
              "test"
            ],
            "type": "string",
            "example": "live"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Prod server key"
          },
          "scope": {
            "enum": [
              "read_write",
              "read_only"
            ],
            "type": "string",
            "example": "read_write"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "revokedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "When set to a FUTURE time the key is rolling (still live until then); a past time means revoked."
          },
          "status": {
            "enum": [
              "active",
              "revoked",
              "expiring"
            ],
            "type": "string",
            "description": "`expiring` = rolled, still serving traffic until `revokedAt`."
          },
          "prefix": {
            "type": "string",
            "example": "sk_live_k1a2b3c4d5.••••••••",
            "description": "Masked prefix — safe to display."
          }
        },
        "required": [
          "id",
          "environment",
          "name",
          "scope",
          "createdAt",
          "lastUsedAt",
          "revokedAt",
          "status",
          "prefix"
        ]
      },
      "RolledKeyRefDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "expiresAt"
        ]
      },
      "CreatedSecretKeyDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "k1a2b3c4d5"
          },
          "environment": {
            "enum": [
              "live",
              "test"
            ],
            "type": "string",
            "example": "live"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Prod server key"
          },
          "scope": {
            "enum": [
              "read_write",
              "read_only"
            ],
            "type": "string",
            "example": "read_write"
          },
          "token": {
            "type": "string",
            "example": "sk_live_k1a2b3c4d5.aVeryLongOpaqueSecret",
            "description": "Full secret token — shown only in this response."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "prefix": {
            "type": "string",
            "example": "sk_live_k1a2b3c4d5.••••••••"
          },
          "status": {
            "enum": [
              "active",
              "revoked",
              "expiring"
            ],
            "type": "string",
            "description": "Present on a roll (always `active`)."
          },
          "replaced": {
            "description": "Present on a roll — the previous key and when it expires.",
            "allOf": [
              {
                "$ref": "#/components/schemas/RolledKeyRefDto"
              }
            ]
          }
        },
        "required": [
          "id",
          "environment",
          "name",
          "scope",
          "token",
          "createdAt",
          "lastUsedAt",
          "prefix"
        ]
      },
      "RollSecretKeyDto": {
        "type": "object",
        "properties": {
          "expireInHours": {
            "type": "number",
            "description": "Grace period, in hours, before the OUTGOING key stops working.\n\nDefaults to `0` — immediate. That is the right default because the usual\nreason to roll is a leak, and a default grace period would leave a\ncompromised credential live. Pass 24–72 for a planned rotation, so servers\ncan be redeployed without downtime. Capped at 168 (7 days).",
            "minimum": 0,
            "maximum": 168,
            "default": 0
          }
        }
      },
      "RevokedKeyDto": {
        "type": "object",
        "properties": {
          "revoked": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "revoked"
        ]
      },
      "WebhookEventsDto": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.delivered",
                "message.viewed",
                "message.clicked",
                "contact.created",
                "contact.unsubscribed",
                "automation.completed"
              ]
            },
            "example": [
              "message.delivered",
              "message.viewed",
              "message.clicked",
              "contact.created",
              "contact.unsubscribed",
              "automation.completed"
            ]
          }
        },
        "required": [
          "events"
        ]
      },
      "WebhookEndpointDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "example": "https://example.com/hooks/onchain"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.delivered",
                "message.viewed",
                "message.clicked",
                "contact.created",
                "contact.unsubscribed",
                "automation.completed"
              ]
            }
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "secretHint": {
            "type": "string",
            "example": "whsec_••••ab12",
            "description": "Masked signing secret — last four characters only."
          },
          "lastDeliveryAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "lastDeliveryStatus": {
            "type": "number",
            "nullable": true,
            "example": 200
          },
          "failureCount": {
            "type": "number",
            "example": 0
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "status",
          "secretHint",
          "lastDeliveryAt",
          "lastDeliveryStatus",
          "failureCount",
          "createdAt"
        ]
      },
      "CreateWebhookDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "example": "https://example.com/hooks/onchain"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.delivered",
                "message.viewed",
                "message.clicked",
                "contact.created",
                "contact.unsubscribed",
                "automation.completed"
              ]
            },
            "description": "Topics to subscribe to. Omit to subscribe to all."
          }
        },
        "required": [
          "url"
        ]
      },
      "CreatedWebhookEndpointDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "example": "https://example.com/hooks/onchain"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.delivered",
                "message.viewed",
                "message.clicked",
                "contact.created",
                "contact.unsubscribed",
                "automation.completed"
              ]
            }
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "secretHint": {
            "type": "string",
            "example": "whsec_••••ab12",
            "description": "Masked signing secret — last four characters only."
          },
          "lastDeliveryAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "lastDeliveryStatus": {
            "type": "number",
            "nullable": true,
            "example": 200
          },
          "failureCount": {
            "type": "number",
            "example": 0
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "secret": {
            "type": "string",
            "example": "whsec_aVeryLongOpaqueSigningSecret",
            "description": "Full signing secret — shown only in this response."
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "status",
          "secretHint",
          "lastDeliveryAt",
          "lastDeliveryStatus",
          "failureCount",
          "createdAt",
          "secret"
        ]
      },
      "UpdateWebhookDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "paused",
            "description": "`active` or `paused`."
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.delivered",
                "message.viewed",
                "message.clicked",
                "contact.created",
                "contact.unsubscribed",
                "automation.completed"
              ]
            }
          }
        }
      },
      "WebhookTestResultDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "description": "True when the endpoint returned a 2xx."
          },
          "status": {
            "type": "number",
            "example": 200,
            "description": "HTTP status the endpoint returned."
          }
        },
        "required": [
          "ok",
          "status"
        ]
      },
      "DeletedWebhookDto": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "deleted"
        ]
      },
      "AskHelpDto": {
        "type": "object",
        "properties": {}
      }
    }
  }
}