{
  "components": {
    "schemas": {
      "AddressDto": {
        "properties": {
          "city": {
            "example": "Austin",
            "type": "string"
          },
          "country": {
            "example": "US",
            "type": "string"
          },
          "line1": {
            "example": "123 Main St",
            "type": "string"
          },
          "line2": {
            "example": "Suite 200",
            "type": "string"
          },
          "postalCode": {
            "example": "78701",
            "type": "string"
          },
          "state": {
            "example": "TX",
            "type": "string"
          }
        },
        "type": "object"
      },
      "AgentResponseDto": {
        "properties": {
          "capabilities": {
            "description": "Capabilities of the AI agent",
            "example": [
              "crm_lookup",
              "kb_search",
              "appointment_booking"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "createdAt": {
            "description": "When the agent was created",
            "example": "2024-01-15T10:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "description": "Description of the AI agent",
            "example": "Handles customer inquiries and support requests",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier for the AI agent",
            "example": "agent_123",
            "type": "string"
          },
          "isActive": {
            "description": "Whether the agent is active",
            "example": true,
            "type": "boolean"
          },
          "maxTokens": {
            "description": "Maximum tokens for AI responses",
            "example": 4000,
            "type": "number"
          },
          "model": {
            "description": "AI model being used",
            "example": "gpt-4",
            "type": "string"
          },
          "name": {
            "description": "Name of the AI agent",
            "example": "Customer Service Agent",
            "type": "string"
          },
          "systemPrompt": {
            "description": "System prompt for the AI agent",
            "example": "You are a helpful customer service assistant...",
            "type": "string"
          },
          "temperature": {
            "description": "Temperature setting for AI responses",
            "example": 0.7,
            "type": "number"
          },
          "updatedAt": {
            "description": "When the agent was last updated",
            "example": "2024-01-15T10:00:00Z",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "systemPrompt",
          "model",
          "temperature",
          "maxTokens",
          "capabilities",
          "isActive",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "AnalyzeCallSentimentDto": {
        "properties": {},
        "type": "object"
      },
      "ApplyLifecyclePresetDto": {
        "properties": {
          "preset": {
            "description": "Preset to apply to lifecycle stages",
            "enum": [
              "B2B_SAAS",
              "HOME_SERVICES",
              "WELLNESS_STUDIO",
              "REAL_ESTATE",
              "INSURANCE_AGENCY",
              "LEGAL_SERVICES",
              "FINANCIAL_SERVICES",
              "SOLAR",
              "ROOFING",
              "PROPERTY_SERVICES"
            ],
            "type": "string"
          }
        },
        "required": [
          "preset"
        ],
        "type": "object"
      },
      "ApplyPostCallRuleTemplateDto": {
        "properties": {
          "applyToAll": {
            "description": "Apply to every unified agent in the organization.",
            "example": false,
            "type": "boolean"
          },
          "mode": {
            "description": "append adds the template rules to existing rules; replace overwrites the target agents rule sets with the template rules.",
            "enum": [
              "append",
              "replace"
            ],
            "example": "append",
            "type": "string"
          },
          "unifiedAgentIds": {
            "description": "Unified agent ids to apply the template to. Required unless applyToAll is true.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "ApplyWorkflowSuggestionDto": {
        "properties": {
          "activate": {
            "description": "Activate the workflow immediately after creation",
            "example": false,
            "type": "boolean"
          },
          "name": {
            "description": "Override the generated workflow name",
            "example": "Post-service review booster",
            "type": "string"
          },
          "templateId": {
            "description": "Identifier of the workflow template to instantiate",
            "example": "general_review_request_follow_up",
            "type": "string"
          }
        },
        "required": [
          "templateId"
        ],
        "type": "object"
      },
      "BatchAnalyzeCallSentimentDto": {
        "properties": {},
        "type": "object"
      },
      "BatchContactEnrichmentDto": {
        "properties": {
          "contactIds": {
            "description": "Contact IDs to enrich.",
            "example": [
              "cuid_1",
              "cuid_2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "refresh": {
            "default": false,
            "description": "If true, bypass cache and recompute enrichment.",
            "type": "boolean"
          }
        },
        "required": [
          "contactIds"
        ],
        "type": "object"
      },
      "BatchCreateTemplateDto": {
        "properties": {
          "category": {
            "description": "Template category",
            "type": "string"
          },
          "description": {
            "description": "Template description",
            "type": "string"
          },
          "edges": {
            "description": "Workflow edges",
            "type": "array"
          },
          "isActive": {
            "default": false,
            "description": "Whether to activate the workflow immediately",
            "type": "boolean"
          },
          "name": {
            "description": "Template name",
            "type": "string"
          },
          "nodes": {
            "description": "Workflow nodes",
            "type": "array"
          },
          "trigger": {
            "description": "Workflow trigger configuration",
            "type": "object"
          }
        },
        "required": [
          "name",
          "description",
          "category",
          "trigger",
          "nodes",
          "edges"
        ],
        "type": "object"
      },
      "BatchCreateTemplatesRequestDto": {
        "properties": {
          "templates": {
            "description": "Array of workflow templates to create",
            "items": {
              "$ref": "#/components/schemas/BatchCreateTemplateDto"
            },
            "type": "array"
          }
        },
        "required": [
          "templates"
        ],
        "type": "object"
      },
      "BatchWorkflowTemplatesDto": {
        "properties": {
          "templates": {
            "items": {
              "$ref": "#/components/schemas/WorkflowTemplateInputDto"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "BulkUpdateCompaniesDto": {
        "properties": {
          "ids": {
            "description": "Company IDs to update",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "updates": {
            "$ref": "#/components/schemas/BulkUpdateCompaniesFieldsDto"
          }
        },
        "required": [
          "ids",
          "updates"
        ],
        "type": "object"
      },
      "BulkUpdateCompaniesFieldsDto": {
        "properties": {
          "ownerId": {
            "description": "Assign owner userId (or null to clear)",
            "nullable": true,
            "type": "string"
          },
          "tags": {
            "description": "Replace tags array",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "BulkUpdateContactsDto": {
        "properties": {
          "ids": {
            "description": "Contact IDs to update",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "updates": {
            "$ref": "#/components/schemas/BulkUpdateContactsFieldsDto"
          }
        },
        "required": [
          "ids",
          "updates"
        ],
        "type": "object"
      },
      "BulkUpdateContactsFieldsDto": {
        "properties": {
          "companyId": {
            "description": "Set companyId (or null to clear)",
            "nullable": true,
            "type": "string"
          },
          "ownerId": {
            "description": "Assign owner userId (or null to clear)",
            "nullable": true,
            "type": "string"
          },
          "status": {
            "enum": [
              "LEAD",
              "ACTIVE",
              "INACTIVE"
            ],
            "type": "string"
          },
          "tags": {
            "description": "Replace tags array",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "BulkUpdateDealsDto": {
        "properties": {
          "ids": {
            "description": "Deal IDs to update",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "updates": {
            "$ref": "#/components/schemas/BulkUpdateDealsFieldsDto"
          }
        },
        "required": [
          "ids",
          "updates"
        ],
        "type": "object"
      },
      "BulkUpdateDealsFieldsDto": {
        "properties": {
          "ownerId": {
            "description": "Assign owner userId (or null to clear)",
            "nullable": true,
            "type": "string"
          },
          "probability": {
            "description": "Set probability (0-100)",
            "type": "number"
          },
          "stageId": {
            "description": "Move deals to stageId",
            "type": "string"
          }
        },
        "type": "object"
      },
      "BusinessProfileDto": {
        "properties": {
          "mcc": {
            "description": "Stripe MCC",
            "example": "1520",
            "type": "string"
          },
          "productDescription": {
            "example": "Residential and commercial roofing services",
            "type": "string"
          },
          "supportEmail": {
            "example": "support@acme.com",
            "type": "string"
          },
          "supportPhone": {
            "example": "+15125551234",
            "type": "string"
          },
          "url": {
            "example": "https://acmeroofing.com",
            "type": "string"
          }
        },
        "type": "object"
      },
      "CheckCreditBalanceDto": {
        "properties": {
          "action": {
            "description": "Action to check credit cost for",
            "enum": [
              "ai_message",
              "ai_voice_minute",
              "ai_resolution",
              "ai_chat_interaction",
              "ai_ad_image",
              "ai_ad_creative",
              "ai_review_reply",
              "sms_segment",
              "sms_message",
              "email_send",
              "dialer_call_minute",
              "workflow_execution",
              "ai_followup",
              "ai_analytics",
              "ai_mining",
              "ai_prediction",
              "ai_revenue",
              "ai_scheduling",
              "ai_experience",
              "ai_performance"
            ],
            "type": "string"
          },
          "quantity": {
            "description": "Quantity of actions",
            "example": 1,
            "type": "number"
          }
        },
        "required": [
          "action",
          "quantity"
        ],
        "type": "object"
      },
      "CompanyDto": {
        "properties": {
          "address": {
            "$ref": "#/components/schemas/AddressDto"
          },
          "name": {
            "example": "Acme Roofing LLC",
            "type": "string"
          },
          "phone": {
            "example": "+15125551234",
            "type": "string"
          },
          "registrationNumber": {
            "example": "123456789",
            "type": "string"
          },
          "taxId": {
            "example": "12-3456789",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContactsImportMappingDto": {
        "properties": {
          "companyName": {
            "description": "Index of the column that maps to company name (0-based)",
            "example": 4,
            "type": "number"
          },
          "email": {
            "description": "Index of the column that maps to email (0-based)",
            "example": 2,
            "type": "number"
          },
          "firstName": {
            "description": "Index of the column that maps to first name (0-based)",
            "example": 0,
            "type": "number"
          },
          "lastName": {
            "description": "Index of the column that maps to last name (0-based)",
            "example": 1,
            "type": "number"
          },
          "phone": {
            "description": "Index of the column that maps to phone (0-based)",
            "example": 3,
            "type": "number"
          }
        },
        "type": "object"
      },
      "CreateAccountLinkDto": {
        "properties": {
          "accountId": {
            "description": "Existing Stripe account id. Defaults to the stored account for this organization.",
            "type": "string"
          },
          "collect": {
            "description": "Prefill everything already provided and only collect outstanding items.",
            "enum": [
              "currently_due",
              "eventually_due"
            ],
            "type": "string"
          },
          "refreshUrl": {
            "example": "https://os.serviceagent.ai/settings/payments?step=retry",
            "type": "string"
          },
          "returnUrl": {
            "example": "https://os.serviceagent.ai/settings/payments?step=complete",
            "type": "string"
          },
          "type": {
            "default": "account_onboarding",
            "enum": [
              "account_onboarding",
              "account_update"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreateActivityDto": {
        "properties": {
          "body": {
            "description": "Activity description/body",
            "example": "Discussed project requirements and timeline",
            "type": "string"
          },
          "callId": {
            "description": "Related call ID",
            "example": "call_abc",
            "type": "string"
          },
          "companyId": {
            "description": "Related company ID",
            "example": "company_456",
            "type": "string"
          },
          "contactId": {
            "description": "Related contact ID",
            "example": "contact_123",
            "type": "string"
          },
          "customJson": {
            "description": "Custom JSON data",
            "example": "{\"customField\": \"value\"}",
            "type": "object"
          },
          "dealId": {
            "description": "Related deal ID",
            "example": "deal_789",
            "type": "string"
          },
          "durationSec": {
            "description": "Duration in seconds",
            "example": 1800,
            "type": "number"
          },
          "messageId": {
            "description": "Related message ID",
            "example": "message_def",
            "type": "string"
          },
          "ownerId": {
            "description": "Activity owner ID",
            "example": "user_123",
            "type": "string"
          },
          "subject": {
            "description": "Activity subject/title",
            "example": "Follow-up call with John Doe",
            "type": "string"
          },
          "type": {
            "description": "Type of activity",
            "enum": [
              "CALL",
              "EMAIL",
              "SMS",
              "MEETING",
              "NOTE",
              "REVIEW_REQUEST",
              "QUOTE_SENT",
              "PAYMENT_RECEIVED"
            ],
            "example": "CALL",
            "type": "string"
          },
          "whenAt": {
            "description": "When the activity occurred or is scheduled",
            "example": "2024-01-15T10:00:00Z",
            "type": "string"
          }
        },
        "required": [
          "type"
        ],
        "type": "object"
      },
      "CreateAgentDto": {
        "properties": {
          "capabilities": {
            "description": "Capabilities of the AI agent",
            "example": [
              "crm_lookup",
              "kb_search",
              "appointment_booking"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "description": {
            "description": "Description of the AI agent",
            "example": "Handles customer inquiries and support requests",
            "type": "string"
          },
          "isActive": {
            "default": true,
            "description": "Whether the agent is active",
            "example": true,
            "type": "boolean"
          },
          "maxTokens": {
            "default": 4000,
            "description": "Maximum tokens for AI responses",
            "example": 4000,
            "maximum": 8000,
            "minimum": 100,
            "type": "number"
          },
          "model": {
            "default": "gpt-4",
            "description": "AI model to use",
            "example": "gpt-4",
            "type": "string"
          },
          "name": {
            "description": "Name of the AI agent",
            "example": "Customer Service Agent",
            "type": "string"
          },
          "systemPrompt": {
            "description": "System prompt for the AI agent",
            "example": "You are a helpful customer service assistant...",
            "type": "string"
          },
          "temperature": {
            "default": 0.7,
            "description": "Temperature for AI responses (0-1)",
            "example": 0.7,
            "maximum": 1,
            "minimum": 0,
            "type": "number"
          }
        },
        "required": [
          "name",
          "systemPrompt"
        ],
        "type": "object"
      },
      "CreateApiKeyDto": {
        "properties": {
          "name": {
            "example": "My API Key",
            "type": "string"
          },
          "scopes": {
            "description": "API key scopes/permissions",
            "example": [
              "crm:read",
              "crm:write"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "name",
          "scopes"
        ],
        "type": "object"
      },
      "CreateAppointmentDto": {
        "properties": {
          "bufferAfterMinutes": {
            "description": "Minutes of buffer time after the appointment",
            "example": 15,
            "type": "number"
          },
          "bufferBeforeMinutes": {
            "description": "Minutes of buffer time before the appointment",
            "example": 15,
            "type": "number"
          },
          "customJson": {
            "additionalProperties": true,
            "description": "Free-form metadata blob attached to the appointment (e.g. partner-specific tags, internal notes). The server stores this passthrough — schema is intentionally open-ended so workflows and integrations can stash whatever they need.",
            "example": {
              "internalNotes": "VIP customer",
              "priority": "high"
            },
            "type": "object"
          },
          "customerEmail": {
            "description": "Required when `customerId` is not provided. Server upserts a `Contact` by email when this path is taken. Ignored when `customerId` is set.",
            "example": "jane@example.com",
            "type": "string"
          },
          "customerId": {
            "description": "Optional: pass the FK of an existing CRM `Contact` to attach the appointment without an email upsert. When provided, `customerName` and `customerEmail` are not required (and are ignored if sent — the contact row is the source of truth). When omitted, the public/inline booking path runs and `customerName` + `customerEmail` are required.",
            "example": "cnt_123",
            "type": "string"
          },
          "customerName": {
            "description": "Required when `customerId` is not provided. Ignored when `customerId` is set.",
            "example": "Jane Smith",
            "type": "string"
          },
          "customerPhone": {
            "example": "+1234567890",
            "type": "string"
          },
          "description": {
            "example": "Please clean the kitchen thoroughly",
            "type": "string"
          },
          "duration": {
            "description": "Duration in minutes. Used to derive endAt when it is omitted.",
            "example": 90,
            "type": "number"
          },
          "endAt": {
            "example": "2024-01-15T12:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "locationId": {
            "description": "Location ID for this appointment (multi-location)",
            "example": "loc_123",
            "type": "string"
          },
          "notes": {
            "example": "Customer prefers morning appointment",
            "type": "string"
          },
          "ownerId": {
            "example": "user-id",
            "type": "string"
          },
          "recurrenceRule": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RecurrenceRuleDto"
              }
            ],
            "description": "Recurrence rule describing how this appointment should repeat"
          },
          "resourceIds": {
            "description": "Resource IDs required for this appointment (rooms/equipment/vehicles)",
            "example": [
              "res_123"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "scheduledAt": {
            "description": "Legacy alias for startAt (ISO 8601).",
            "example": "2024-01-15T10:00:00Z",
            "type": "string"
          },
          "serviceId": {
            "description": "Optional. Defaults to the first active service offering when omitted.",
            "example": "service-id",
            "type": "string"
          },
          "serviceOfferingId": {
            "description": "Alias for serviceId kept for backward compatibility.",
            "example": "service-offering-id",
            "type": "string"
          },
          "staffId": {
            "description": "Optional. Defaults to the first active staff member when omitted.",
            "example": "staff-id",
            "type": "string"
          },
          "startAt": {
            "example": "2024-01-15T10:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "example": "scheduled",
            "type": "string"
          },
          "title": {
            "example": "House Cleaning Service",
            "type": "string"
          }
        },
        "required": [
          "startAt"
        ],
        "type": "object"
      },
      "CreateBreakDto": {
        "properties": {
          "dayOfWeek": {
            "example": 1,
            "maximum": 6,
            "minimum": 0,
            "type": "number"
          },
          "endTime": {
            "example": "13:00",
            "type": "string"
          },
          "isRecurring": {
            "default": true,
            "example": true,
            "type": "boolean"
          },
          "startTime": {
            "example": "12:00",
            "type": "string"
          },
          "title": {
            "example": "Lunch Break",
            "type": "string"
          }
        },
        "required": [
          "title",
          "startTime",
          "endTime",
          "dayOfWeek",
          "isRecurring"
        ],
        "type": "object"
      },
      "CreateCompanyDto": {
        "properties": {
          "address": {
            "example": "123 Main St",
            "type": "string"
          },
          "addressJson": {
            "example": {
              "city": "Anytown",
              "state": "CA",
              "street": "123 Main St",
              "zip": "12345"
            },
            "type": "object"
          },
          "customJson": {
            "example": {
              "customField": "value"
            },
            "type": "object"
          },
          "domain": {
            "example": "acme.com",
            "type": "string"
          },
          "industry": {
            "example": "Technology",
            "type": "string"
          },
          "name": {
            "example": "Acme Corporation",
            "type": "string"
          },
          "phone": {
            "example": "+1234567890",
            "type": "string"
          },
          "size": {
            "example": "50-100",
            "type": "string"
          },
          "tags": {
            "example": [
              "tag1",
              "tag2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "website": {
            "example": "https://acme.com",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateConnectAccountDto": {
        "properties": {
          "businessProfile": {
            "$ref": "#/components/schemas/BusinessProfileDto"
          },
          "businessType": {
            "enum": [
              "individual",
              "company",
              "non_profit",
              "government_entity"
            ],
            "example": "company",
            "type": "string"
          },
          "company": {
            "$ref": "#/components/schemas/CompanyDto"
          },
          "country": {
            "default": "US",
            "example": "US",
            "type": "string"
          },
          "email": {
            "example": "billing@acme.com",
            "type": "string"
          },
          "externalAccount": {
            "$ref": "#/components/schemas/ExternalAccountDto"
          },
          "metadata": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          },
          "owners": {
            "items": {
              "$ref": "#/components/schemas/PersonDto"
            },
            "type": "array"
          },
          "representative": {
            "$ref": "#/components/schemas/PersonDto"
          },
          "settings": {
            "$ref": "#/components/schemas/SettingsDto"
          },
          "tosAcceptance": {
            "$ref": "#/components/schemas/TosAcceptanceDto"
          },
          "type": {
            "default": "express",
            "enum": [
              "express",
              "standard"
            ],
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "type": "object"
      },
      "CreateContactDto": {
        "properties": {
          "behavioralProfile": {
            "description": "Behavioral intelligence profile",
            "example": {
              "communicationStyle": "FORMAL",
              "decisionMakingStyle": "ANALYTICAL",
              "engagementFrequency": "WEEKLY",
              "engagementScore": 75,
              "lastEngagementAt": "2024-01-15T10:00:00Z",
              "preferredChannel": "EMAIL",
              "responseRate": 80,
              "riskTolerance": "MEDIUM",
              "urgencyPreference": "HIGH"
            },
            "type": "object"
          },
          "companyId": {
            "example": "company-id",
            "type": "string"
          },
          "contextualProfile": {
            "description": "Contextual intelligence profile",
            "example": {
              "budgetRange": "50K_100K",
              "challenges": [
                "Legacy systems"
              ],
              "companySize": "MEDIUM",
              "competitors": [
                "Competitor A",
                "Competitor B"
              ],
              "currentSolutions": [
                "Current solution X"
              ],
              "decisionTimeline": "3_MONTHS",
              "goals": [
                "Increase efficiency",
                "Reduce costs"
              ],
              "industry": "Technology",
              "painPoints": [
                "Integration challenges",
                "Cost concerns"
              ],
              "successMetrics": [
                "ROI",
                "User adoption"
              ]
            },
            "type": "object"
          },
          "customJson": {
            "example": {
              "customField": "value"
            },
            "type": "object"
          },
          "email": {
            "example": "john.doe@example.com",
            "type": "string"
          },
          "firstName": {
            "example": "John",
            "type": "string"
          },
          "identityProfile": {
            "description": "Enhanced identity information",
            "example": {
              "avatar": "https://example.com/avatar.jpg",
              "department": "Sales",
              "language": "en",
              "preferredName": "Johnny",
              "role": "Decision Maker",
              "seniority": "SENIOR",
              "socialProfiles": [],
              "timezone": "America/New_York",
              "title": "VP of Sales"
            },
            "type": "object"
          },
          "lastName": {
            "example": "Doe",
            "type": "string"
          },
          "leadScore": {
            "description": "Explicit lead score override. If omitted the system auto-calculates.",
            "example": 65,
            "type": "number"
          },
          "lifecycleStageId": {
            "description": "Lifecycle stage identifier.",
            "example": "stage_cuid",
            "type": "string"
          },
          "lifecycleStageKey": {
            "description": "Lifecycle stage key (e.g., MQL, SQL). Takes precedence over lifecycleStageId.",
            "example": "SQL",
            "type": "string"
          },
          "ownerId": {
            "example": "user-id",
            "type": "string"
          },
          "phone": {
            "example": "+1234567890",
            "type": "string"
          },
          "predictiveProfile": {
            "description": "Predictive intelligence profile",
            "example": {
              "acquisitionCost": 5000,
              "estimatedDealSize": 50000,
              "lifetimeValue": 150000,
              "likelihoodToBuy": 75,
              "nextBestAction": "Schedule demo call",
              "nextMilestone": "Technical evaluation",
              "optimalContactChannel": "PHONE",
              "optimalContactTime": "Tuesday 2-4 PM",
              "predictedChurnDate": null
            },
            "type": "object"
          },
          "relationshipProfile": {
            "description": "Relationship intelligence profile",
            "example": {
              "churnRisk": 20,
              "influenceLevel": "HIGH",
              "loyaltyScore": 80,
              "networkConnections": [],
              "referralPotential": 70,
              "relationshipStage": "WARM",
              "relationshipStrength": 85
            },
            "type": "object"
          },
          "status": {
            "example": "LEAD",
            "type": "string"
          },
          "tags": {
            "example": [
              "tag1",
              "tag2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "firstName",
          "lastName"
        ],
        "type": "object"
      },
      "CreateDealDto": {
        "properties": {
          "amountCents": {
            "example": 250000,
            "type": "number"
          },
          "closeDate": {
            "example": "2025-12-31",
            "type": "string"
          },
          "companyId": {
            "example": "comp_123",
            "type": "string"
          },
          "contactId": {
            "example": "contact_123",
            "type": "string"
          },
          "currency": {
            "example": "USD",
            "type": "string"
          },
          "ownerId": {
            "example": "user_123",
            "type": "string"
          },
          "pipelineId": {
            "example": "pipe_123",
            "type": "string"
          },
          "source": {
            "example": "inbound",
            "type": "string"
          },
          "stage": {
            "description": "Deprecated alias for stageId. Will be coerced into stageId if provided.",
            "example": "stage_legacy",
            "type": "string"
          },
          "stageId": {
            "example": "stage_123",
            "type": "string"
          },
          "status": {
            "enum": [
              "OPEN",
              "WON",
              "LOST"
            ],
            "example": "OPEN",
            "type": "string"
          },
          "title": {
            "example": "New Website Project",
            "type": "string"
          }
        },
        "required": [
          "title"
        ],
        "type": "object"
      },
      "CreateEmailTemplateDto": {
        "properties": {
          "body": {
            "description": "Alias for bodyHtml",
            "example": "<html>...</html>",
            "type": "string"
          },
          "bodyHtml": {
            "description": "Email body in HTML format with template variables",
            "example": "<h2>Proposal Follow-up</h2><p>Dear {{contact.firstName}},</p><p>I wanted to follow up on the proposal...</p>",
            "type": "string"
          },
          "category": {
            "description": "Template category",
            "example": "sales",
            "type": "string"
          },
          "name": {
            "description": "Template name",
            "example": "Proposal Follow-up",
            "type": "string"
          },
          "subject": {
            "description": "Email subject with template variables",
            "example": "Follow-up: {{proposal.title}}",
            "type": "string"
          },
          "variables": {
            "description": "Array of template variables used",
            "example": [
              "contact.firstName",
              "proposal.title",
              "user.name"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "name",
          "subject",
          "bodyHtml",
          "category"
        ],
        "type": "object"
      },
      "CreateInvoiceDto": {
        "properties": {
          "amount": {
            "example": 10000,
            "type": "number"
          },
          "autoSend": {
            "example": false,
            "type": "boolean"
          },
          "contactId": {
            "example": "contact-id",
            "type": "string"
          },
          "currency": {
            "example": "USD",
            "type": "string"
          },
          "description": {
            "example": "Invoice description",
            "type": "string"
          },
          "dueDate": {
            "example": "2025-12-31",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/InvoiceItemDto"
            },
            "type": "array"
          },
          "notes": {
            "example": "Payment notes",
            "type": "string"
          },
          "number": {
            "example": "INV-001",
            "type": "string"
          },
          "paymentTerms": {
            "example": "Net 30",
            "type": "string"
          },
          "template": {
            "example": "default",
            "type": "string"
          }
        },
        "required": [
          "amount",
          "description"
        ],
        "type": "object"
      },
      "CreateKbArticleDto": {
        "properties": {
          "aiAgentId": {
            "example": "cleaning",
            "type": "string"
          },
          "category": {
            "example": "pricing",
            "type": "string"
          },
          "content": {
            "example": "Our standard service includes cleaning, maintenance, and repair work...",
            "type": "string"
          },
          "fileHandles": {
            "description": "Filestack file handles for attachments",
            "example": [
              "handle1",
              "handle2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tags": {
            "example": [
              "pricing",
              "services",
              "costs"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "example": "Service Pricing Information",
            "type": "string"
          }
        },
        "required": [
          "title",
          "content"
        ],
        "type": "object"
      },
      "CreateKnowledgeBaseDto": {
        "properties": {
          "description": {
            "description": "Optional description",
            "example": "Public-facing FAQs and policies",
            "type": "string"
          },
          "name": {
            "description": "Knowledge base name",
            "example": "Support FAQ",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateLocationDto": {
        "properties": {
          "address": {
            "description": "Primary address of the location",
            "example": "123 Main St, Dallas, TX 75201",
            "type": "string"
          },
          "addressJson": {
            "description": "Structured address object (optional). Useful for maps + formatting.",
            "example": {
              "city": "Dallas",
              "country": "US",
              "state": "TX",
              "street": "123 Main St",
              "zip": "75201"
            },
            "type": "object"
          },
          "googlePlaceId": {
            "description": "Google Place ID for this location (optional).",
            "example": "ChIJN1t_tDeuEmsRUsoyG83frY4",
            "type": "string"
          },
          "isActive": {
            "description": "Whether the location is active",
            "example": true,
            "type": "boolean"
          },
          "latitude": {
            "description": "Latitude (optional)",
            "example": 32.7767,
            "type": "number"
          },
          "longitude": {
            "description": "Longitude (optional)",
            "example": -96.797,
            "type": "number"
          },
          "marketingNapOverride": {
            "description": "Location-specific override for listings NAP data",
            "example": {
              "address": {
                "city": "Dallas",
                "state": "TX",
                "street": "123 Main St",
                "zip": "75201"
              },
              "name": "Acme Heating & Air - Downtown",
              "phone": "+1-555-0123"
            },
            "type": "object"
          },
          "name": {
            "description": "Display name for the location",
            "example": "Downtown Office",
            "type": "string"
          },
          "phone": {
            "description": "Contact phone number for the location",
            "example": "+1-555-0123",
            "type": "string"
          },
          "serviceAreaZipCodes": {
            "description": "Zip codes served by this location for localized marketing",
            "example": [
              "75201",
              "75202",
              "75001"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "timezone": {
            "description": "Timezone identifier for scheduling and availability",
            "example": "America/Chicago",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateManualSurveyInvitationDto": {
        "properties": {
          "appointmentId": {
            "type": "string"
          },
          "callId": {
            "type": "string"
          },
          "campaignId": {
            "type": "string"
          },
          "channel": {
            "enum": [
              "EMAIL",
              "SMS",
              "WHATSAPP",
              "CHAT_WIDGET",
              "TICKET",
              "CALL_IVR"
            ],
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "contactId": {
            "type": "string"
          },
          "deliveryMetadata": {
            "type": "object"
          },
          "sendAt": {
            "description": "ISO string for when to send invite; defaults to immediate",
            "type": "string"
          },
          "templateId": {
            "type": "string"
          },
          "ticketId": {
            "type": "string"
          },
          "triggerId": {
            "type": "string"
          },
          "workflowRunId": {
            "type": "string"
          }
        },
        "required": [
          "templateId",
          "contactId",
          "channel"
        ],
        "type": "object"
      },
      "CreatePaymentLinkDto": {
        "properties": {
          "amount": {
            "description": "Amount in cents",
            "example": 5000,
            "type": "number"
          },
          "contactId": {
            "example": "contact-id",
            "type": "string"
          },
          "currency": {
            "example": "usd",
            "type": "string"
          },
          "customerEmail": {
            "example": "customer@example.com",
            "type": "string"
          },
          "customerName": {
            "example": "John Doe",
            "type": "string"
          },
          "description": {
            "example": "Service payment",
            "type": "string"
          },
          "invoiceId": {
            "example": "invoice-id",
            "type": "string"
          },
          "metadata": {
            "example": {
              "source": "appointment"
            },
            "type": "object"
          }
        },
        "required": [
          "amount",
          "description"
        ],
        "type": "object"
      },
      "CreatePaymentMethodDto": {
        "properties": {
          "paymentMethodId": {
            "description": "Stripe payment method ID",
            "example": "pm_1234567890",
            "type": "string"
          },
          "setAsDefault": {
            "description": "Set as default payment method",
            "example": true,
            "type": "boolean"
          }
        },
        "required": [
          "paymentMethodId"
        ],
        "type": "object"
      },
      "CreatePayoutDto": {
        "properties": {
          "amountCents": {
            "description": "Payout amount in cents",
            "example": 2500,
            "type": "number"
          },
          "currency": {
            "description": "Three-letter ISO currency code",
            "example": "usd",
            "type": "string"
          }
        },
        "required": [
          "amountCents"
        ],
        "type": "object"
      },
      "CreateReviewCommentDto": {
        "properties": {
          "body": {
            "example": "Called customer, offered re-service tomorrow.",
            "type": "string"
          }
        },
        "required": [
          "body"
        ],
        "type": "object"
      },
      "CreateReviewRequestDto": {
        "properties": {
          "appointmentId": {
            "description": "Appointment that completed",
            "type": "string"
          },
          "channels": {
            "items": {
              "enum": [
                "email",
                "sms"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "contactId": {
            "description": "Contact to request a review from (legacy field)",
            "type": "string"
          },
          "contactIds": {
            "description": "Contacts to request reviews from (spec field)",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "jobId": {
            "description": "Job that completed",
            "type": "string"
          },
          "locationId": {
            "description": "Location associated with the review request",
            "type": "string"
          },
          "messageOverrides": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReviewRequestMessageDto"
              }
            ],
            "description": "Override default messaging content"
          },
          "sendAt": {
            "description": "Schedule the request to send after this time",
            "type": "string"
          },
          "templateId": {
            "description": "Optional template ID override (applies to the selected channel). If omitted, uses org/location review request settings.",
            "type": "string"
          },
          "templateOverride": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReviewTemplateOverrideDto"
              }
            ],
            "description": "Override template subject/body (spec field)"
          }
        },
        "type": "object"
      },
      "CreateReviewRequestResponseDto": {
        "properties": {
          "appointmentId": {
            "type": "string"
          },
          "channel": {
            "type": "object"
          },
          "contactId": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "jobId": {
            "type": "string"
          },
          "locationId": {
            "type": "string"
          },
          "sendAfter": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "channel",
          "status",
          "createdAt"
        ],
        "type": "object"
      },
      "CreateSavedFilterDto": {
        "properties": {
          "criteria": {
            "description": "Filter criteria object using the same keys as list endpoints",
            "example": {
              "score": {
                "gte": 80
              },
              "status": "active",
              "tags": [
                "vip"
              ]
            },
            "type": "object"
          },
          "isFavorite": {
            "default": false,
            "type": "boolean"
          },
          "name": {
            "example": "High Value Leads",
            "maxLength": 100,
            "minLength": 1,
            "type": "string"
          },
          "type": {
            "enum": [
              "contacts",
              "companies",
              "deals"
            ],
            "example": "contacts",
            "type": "string"
          }
        },
        "required": [
          "name",
          "type",
          "criteria"
        ],
        "type": "object"
      },
      "CreateServiceRequestDto": {
        "properties": {
          "email": {
            "description": "Customer email",
            "type": "string"
          },
          "message": {
            "description": "Optional service request note",
            "type": "string"
          },
          "name": {
            "description": "Customer full name",
            "type": "string"
          },
          "phone": {
            "description": "Customer phone number",
            "type": "string"
          },
          "widgetKey": {
            "description": "Public widget key that identifies organization",
            "type": "string"
          },
          "zip": {
            "description": "Customer ZIP/postal code",
            "type": "string"
          }
        },
        "required": [
          "widgetKey",
          "name",
          "email",
          "zip"
        ],
        "type": "object"
      },
      "CreateStaffDto": {
        "properties": {
          "bio": {
            "example": "Experienced HVAC technician with 10+ years",
            "type": "string"
          },
          "calendarId": {
            "example": "google-calendar-id",
            "type": "string"
          },
          "isActive": {
            "example": true,
            "type": "boolean"
          },
          "skills": {
            "example": [
              "hvac",
              "maintenance",
              "repair"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "example": "Senior Technician",
            "type": "string"
          },
          "userId": {
            "example": "user-id",
            "type": "string"
          }
        },
        "required": [
          "userId"
        ],
        "type": "object"
      },
      "CreateSurveyCampaignDto": {
        "properties": {
          "channelStrategy": {
            "description": "Channel sequencing, review thresholds, etc.",
            "type": "object"
          },
          "cooldownDays": {
            "description": "Days before the same contact can receive this campaign again",
            "example": 30,
            "type": "number"
          },
          "defaultDelayMinutes": {
            "description": "Delay in minutes before sending invitations",
            "example": 120,
            "type": "number"
          },
          "name": {
            "example": "Post-appointment follow-up",
            "type": "string"
          },
          "targetFilters": {
            "description": "Targeting filters (services, staff, tags, etc.)",
            "type": "object"
          },
          "templateId": {
            "type": "string"
          }
        },
        "required": [
          "templateId",
          "name",
          "defaultDelayMinutes"
        ],
        "type": "object"
      },
      "CreateSurveyFrontendDto": {
        "properties": {
          "description": {
            "type": "string"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/FrontendSurveyQuestionDto"
            },
            "type": "array"
          },
          "settings": {
            "description": "Frontend settings bag (best-effort stored in theme.metadata)",
            "type": "object"
          },
          "title": {
            "type": "string"
          }
        },
        "required": [
          "title",
          "questions"
        ],
        "type": "object"
      },
      "CreateSurveyResponseDto": {
        "properties": {
          "answers": {
            "type": "object"
          },
          "comment": {
            "type": "string"
          },
          "invitationId": {
            "type": "string"
          },
          "respondedAt": {
            "description": "Override response timestamp (ISO string)",
            "type": "string"
          },
          "score": {
            "maximum": 10,
            "minimum": 0,
            "type": "number"
          },
          "sentiment": {
            "type": "string"
          }
        },
        "required": [
          "invitationId"
        ],
        "type": "object"
      },
      "CreateSurveyTemplateDto": {
        "properties": {
          "channels": {
            "example": [
              "EMAIL",
              "SMS"
            ],
            "items": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "description": {
            "example": "Sent 2 hours after appointment completion",
            "type": "string"
          },
          "name": {
            "example": "Post-Appointment NPS",
            "type": "string"
          },
          "questions": {
            "description": "Ordered list of questions to display",
            "items": {
              "$ref": "#/components/schemas/SurveyQuestionInputDto"
            },
            "type": "array"
          },
          "scoreType": {
            "enum": [
              "NPS",
              "CSAT",
              "CES",
              "CUSTOM"
            ],
            "example": "NPS",
            "type": "string"
          },
          "theme": {
            "description": "Custom theme (colors, fonts, etc.)",
            "type": "object"
          }
        },
        "required": [
          "name",
          "scoreType",
          "channels",
          "questions"
        ],
        "type": "object"
      },
      "CreateSurveyTriggerDto": {
        "properties": {
          "delayMinutes": {
            "description": "Delay in minutes before sending invitations",
            "example": 120,
            "type": "number"
          },
          "entityFilters": {
            "description": "Filters for matching events (serviceIds, staffIds, etc.)",
            "type": "object"
          },
          "isActive": {
            "default": true,
            "type": "boolean"
          },
          "type": {
            "enum": [
              "APPOINTMENT_COMPLETED",
              "TICKET_RESOLVED",
              "CALL_COMPLETED",
              "CHAT_ENDED",
              "WORKFLOW_NODE",
              "MANUAL"
            ],
            "type": "string"
          }
        },
        "required": [
          "type",
          "delayMinutes"
        ],
        "type": "object"
      },
      "CreateTaskDto": {
        "properties": {
          "companyId": {
            "description": "Related company ID",
            "example": "company_456",
            "type": "string"
          },
          "contactId": {
            "description": "Related contact ID",
            "example": "contact_123",
            "type": "string"
          },
          "customJson": {
            "description": "Custom JSON data",
            "example": "{\"customField\": \"value\"}",
            "type": "object"
          },
          "dealId": {
            "description": "Related deal ID",
            "example": "deal_789",
            "type": "string"
          },
          "description": {
            "description": "Task description",
            "example": "Call client to discuss project timeline",
            "type": "string"
          },
          "dueAt": {
            "description": "Task due date",
            "example": "2024-01-15T17:00:00Z",
            "type": "string"
          },
          "estimatedHours": {
            "description": "Estimated hours for this task",
            "example": 2.5,
            "type": "number"
          },
          "ownerId": {
            "description": "Task owner ID",
            "example": "user_123",
            "type": "string"
          },
          "phaseId": {
            "description": "Related project phase ID",
            "example": "phase_456",
            "type": "string"
          },
          "priority": {
            "description": "Task priority",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ],
            "example": "HIGH",
            "type": "string"
          },
          "projectId": {
            "description": "Related project ID",
            "example": "project_123",
            "type": "string"
          },
          "stage": {
            "description": "Task stage (e.g., todo, in_progress, review, done)",
            "example": "todo",
            "type": "string"
          },
          "status": {
            "description": "Task status",
            "enum": [
              "OPEN",
              "DONE"
            ],
            "example": "OPEN",
            "type": "string"
          },
          "title": {
            "description": "Task title",
            "example": "Follow up with client",
            "type": "string"
          }
        },
        "required": [
          "title"
        ],
        "type": "object"
      },
      "CreateTimeOffDto": {
        "properties": {
          "endDate": {
            "example": "2025-02-05",
            "type": "string"
          },
          "reason": {
            "example": "Family vacation",
            "type": "string"
          },
          "startDate": {
            "example": "2025-02-01",
            "type": "string"
          },
          "type": {
            "default": "OTHER",
            "enum": [
              "VACATION",
              "SICK",
              "PERSONAL",
              "OTHER"
            ],
            "type": "string"
          }
        },
        "required": [
          "startDate",
          "endDate",
          "type",
          "reason"
        ],
        "type": "object"
      },
      "CreateTimelineEventDto": {
        "properties": {
          "category": {
            "description": "Category of the event",
            "example": "call",
            "type": "string"
          },
          "description": {
            "description": "Description of the event",
            "example": "Discussed project requirements and timeline",
            "type": "string"
          },
          "metadata": {
            "description": "Additional metadata for the event",
            "example": {
              "duration": 1800,
              "outcome": "positive"
            },
            "type": "object"
          },
          "source": {
            "description": "Source of the event",
            "enum": [
              "MANUAL",
              "AUTOMATED",
              "INTEGRATION",
              "AI_GENERATED"
            ],
            "example": "MANUAL",
            "type": "string"
          },
          "timestamp": {
            "description": "When the event occurred",
            "example": "2024-01-15T10:00:00Z",
            "type": "string"
          },
          "title": {
            "description": "Title of the event",
            "example": "Phone call with John Doe",
            "type": "string"
          },
          "type": {
            "description": "Type of timeline event",
            "enum": [
              "INTERACTION",
              "MILESTONE",
              "ACHIEVEMENT",
              "CHANGE",
              "ALERT"
            ],
            "example": "INTERACTION",
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "source"
        ],
        "type": "object"
      },
      "CreateUnifiedAgentDto": {
        "properties": {},
        "type": "object"
      },
      "CreateWebhookDto": {
        "properties": {
          "events": {
            "description": "List of events to subscribe to",
            "example": [
              "company.created",
              "contact.updated",
              "deal.won"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "secret": {
            "description": "Custom webhook secret (auto-generated if not provided)",
            "example": "whsec_your_webhook_secret_here",
            "type": "string"
          },
          "url": {
            "example": "https://api.example.com/webhooks",
            "type": "string"
          }
        },
        "required": [
          "url",
          "events"
        ],
        "type": "object"
      },
      "CreateWidgetSessionDto": {
        "properties": {},
        "type": "object"
      },
      "CreateWorkflowDto": {
        "properties": {
          "definition": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowDefinitionDto"
              }
            ],
            "deprecated": true,
            "description": "Builder-shaped graph wrapper. The server lifts `definition.nodes` / `definition.edges` onto the root before validation. Prefer sending `nodes` / `edges` at the root directly."
          },
          "description": {
            "example": "Automates the customer onboarding process",
            "type": "string"
          },
          "edges": {
            "description": "Workflow graph edges. Edges referencing unknown nodes are dropped server-side rather than 400ing the save.",
            "items": {
              "$ref": "#/components/schemas/WorkflowEdgeDto"
            },
            "type": "array"
          },
          "isActive": {
            "example": true,
            "type": "boolean"
          },
          "locationId": {
            "description": "Multi-location v1: optional locationId. If omitted, defaults to the active location (X-Location-Id) when present; otherwise creates a global default.",
            "nullable": true,
            "type": "string"
          },
          "metadata": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowMetadataDto"
              }
            ],
            "description": "Workflow metadata including AI conversation history and builder source tags."
          },
          "name": {
            "example": "New Customer Onboarding",
            "type": "string"
          },
          "nodes": {
            "description": "Workflow graph nodes. Sparse/null entries emitted by the builder during edits are tolerated and stripped server-side.",
            "items": {
              "$ref": "#/components/schemas/WorkflowNodeDto"
            },
            "type": "array"
          },
          "trigger": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowTriggerDto"
              }
            ],
            "description": "Trigger object for quick-start templates (type + config)."
          },
          "triggerConfig": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowTriggerConfigDto"
              }
            ],
            "description": "Trigger configuration scoped to `triggerType`. Cron schedule for SCHEDULED, event filter for EVENT, webhook secret for WEBHOOK, ignored for MANUAL."
          },
          "triggerType": {
            "enum": [
              "MANUAL",
              "SCHEDULED",
              "EVENT",
              "WEBHOOK"
            ],
            "example": "MANUAL",
            "type": "string"
          }
        },
        "required": [
          "name",
          "triggerType"
        ],
        "type": "object"
      },
      "DateOfBirthDto": {
        "properties": {
          "day": {
            "example": 12,
            "type": "number"
          },
          "month": {
            "example": 8,
            "type": "number"
          },
          "year": {
            "example": 1985,
            "type": "number"
          }
        },
        "required": [
          "day",
          "month",
          "year"
        ],
        "type": "object"
      },
      "DedupeContactsDto": {
        "properties": {
          "duplicateIds": {
            "example": [
              "duplicate-contact-id-1",
              "duplicate-contact-id-2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "primaryId": {
            "example": "primary-contact-id",
            "type": "string"
          }
        },
        "required": [
          "primaryId",
          "duplicateIds"
        ],
        "type": "object"
      },
      "DuplicateSurveyTemplateDto": {
        "properties": {
          "name": {
            "example": "Post-Appointment NPS (Copy)",
            "type": "string"
          }
        },
        "type": "object"
      },
      "DuplicateWorkflowDto": {
        "properties": {
          "name": {
            "description": "Override name for the duplicated workflow",
            "type": "string"
          }
        },
        "type": "object"
      },
      "EnableChatChannelDto": {
        "properties": {},
        "type": "object"
      },
      "EnableVoiceChannelDto": {
        "properties": {},
        "type": "object"
      },
      "ExecuteContactsImportDto": {
        "properties": {
          "customFieldMapping": {
            "description": "Optional mapping of CSV column index (0-based) to custom field key (e.g. {\"4\":\"lead_source\"})",
            "example": {
              "4": "lead_source",
              "5": "industry"
            },
            "type": "object"
          },
          "fileHandle": {
            "description": "Filestack handle returned from the analyze call",
            "example": "ABC123xyz",
            "type": "string"
          },
          "mapping": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContactsImportMappingDto"
              }
            ],
            "description": "Field-to-column mapping selected by the user"
          }
        },
        "required": [
          "fileHandle",
          "mapping"
        ],
        "type": "object"
      },
      "ExecuteHybridContactsImportDto": {
        "properties": {
          "createReviewTask": {
            "description": "If true, create a single review task containing queued duplicate candidates. Recommended for hybrid mode.",
            "example": true,
            "type": "boolean"
          },
          "customFieldMapping": {
            "description": "Optional mapping of CSV column index (0-based) to custom field key (e.g. {\"4\":\"lead_source\"})",
            "example": {
              "4": "lead_source",
              "5": "industry"
            },
            "type": "object"
          },
          "fileHandle": {
            "description": "Filestack handle returned from the analyze call",
            "example": "ABC123xyz",
            "type": "string"
          },
          "mapping": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContactsImportMappingDto"
              }
            ],
            "description": "Field-to-column mapping selected by the user"
          }
        },
        "required": [
          "fileHandle",
          "mapping"
        ],
        "type": "object"
      },
      "ExternalAccountDto": {
        "properties": {
          "bankAccount": {
            "$ref": "#/components/schemas/ExternalBankAccountDto"
          },
          "token": {
            "description": "Existing bank account token",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ExternalBankAccountDto": {
        "properties": {
          "accountHolderName": {
            "example": "Acme Roofing LLC",
            "type": "string"
          },
          "accountHolderType": {
            "enum": [
              "company",
              "individual"
            ],
            "example": "company",
            "type": "string"
          },
          "accountNumber": {
            "example": "000123456789",
            "type": "string"
          },
          "country": {
            "example": "US",
            "type": "string"
          },
          "currency": {
            "example": "usd",
            "type": "string"
          },
          "routingNumber": {
            "example": "110000000",
            "type": "string"
          }
        },
        "required": [
          "accountNumber"
        ],
        "type": "object"
      },
      "FrontendSurveyQuestionDto": {
        "properties": {
          "id": {
            "description": "Optional client-side identifier",
            "type": "string"
          },
          "options": {
            "type": "object"
          },
          "required": {
            "default": false,
            "type": "boolean"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "title"
        ],
        "type": "object"
      },
      "GenerateReviewReplyDto": {
        "properties": {
          "instructions": {
            "example": "Mention our 24/7 emergency support in the reply.",
            "type": "string"
          },
          "tone": {
            "description": "Tone or style hint for the AI-generated reply",
            "example": "empathetic",
            "type": "string"
          }
        },
        "type": "object"
      },
      "GenerateWorkflowWithAiDto": {
        "properties": {
          "context": {
            "$ref": "#/components/schemas/WorkflowAiGenerateContextDto"
          },
          "conversationHistory": {
            "items": {
              "$ref": "#/components/schemas/WorkflowAiConversationMessageDto"
            },
            "type": "array"
          },
          "prompt": {
            "example": "Send appointment reminder 24 hours before scheduled time",
            "type": "string"
          }
        },
        "required": [
          "prompt"
        ],
        "type": "object"
      },
      "ImportReviewRecordDto": {
        "properties": {
          "authorName": {
            "example": "Jane Doe",
            "type": "string"
          },
          "authorUrl": {
            "example": "https://www.trustpilot.com/users/xyz",
            "type": "string"
          },
          "body": {
            "example": "They were on time and professional.",
            "type": "string"
          },
          "externalReviewId": {
            "description": "Stable external identifier from the provider",
            "example": "tp_abc123",
            "type": "string"
          },
          "externalUrl": {
            "description": "Optional URL to the review on the provider",
            "example": "https://www.trustpilot.com/reviews/xyz",
            "type": "string"
          },
          "postedAt": {
            "example": "2025-12-01T10:00:00.000Z",
            "type": "string"
          },
          "rating": {
            "example": 5,
            "maximum": 5,
            "minimum": 1,
            "type": "number"
          },
          "source": {
            "description": "Provider/source key",
            "example": "trustpilot",
            "type": "string"
          },
          "title": {
            "example": "Great service",
            "type": "string"
          }
        },
        "required": [
          "source",
          "externalReviewId"
        ],
        "type": "object"
      },
      "ImportReviewsDto": {
        "properties": {
          "reviews": {
            "items": {
              "$ref": "#/components/schemas/ImportReviewRecordDto"
            },
            "type": "array"
          }
        },
        "required": [
          "reviews"
        ],
        "type": "object"
      },
      "InitiateOutboundCallDto": {
        "properties": {},
        "type": "object"
      },
      "InitiateTestCallDto": {
        "properties": {
          "phoneNumber": {
            "description": "User's phone number to call (E.164).",
            "example": "+12025551234",
            "type": "string"
          }
        },
        "required": [
          "phoneNumber"
        ],
        "type": "object"
      },
      "InsightActionDto": {
        "properties": {
          "action": {
            "description": "Description of the action taken",
            "example": "Scheduled follow-up call for next week",
            "type": "string"
          },
          "metadata": {
            "description": "Additional metadata about the action",
            "example": {
              "scheduledDate": "2024-01-15T10:00:00Z"
            },
            "type": "object"
          },
          "notes": {
            "description": "Additional notes about the action",
            "example": "Discuss pricing options",
            "type": "string"
          }
        },
        "required": [
          "action"
        ],
        "type": "object"
      },
      "InstallExchangeDto": {
        "properties": {
          "installToken": {
            "description": "Install token from /install/start",
            "type": "string"
          }
        },
        "required": [
          "installToken"
        ],
        "type": "object"
      },
      "InstallStartDto": {
        "properties": {
          "client": {
            "description": "Free-form sub-identifier for the originating client (e.g. MCP server version \"@serviceagent/mcp@1.0.3\"). Logged for debugging only; not validated against an enum.",
            "maxLength": 120,
            "type": "string"
          },
          "framework": {
            "description": "Framework of the calling project (separate from `platform`, which is the install source). Logged in install settings for telemetry.",
            "enum": [
              "nextjs",
              "react",
              "vite",
              "astro",
              "remix",
              "svelte",
              "nuxt",
              "html",
              "node",
              "unknown"
            ],
            "type": "string"
          },
          "module": {
            "default": "chat",
            "description": "Requested module to provision (v1 ships chat)",
            "enum": [
              "chat"
            ],
            "type": "string"
          },
          "platform": {
            "description": "Install source — the AI builder, IDE, or MCP client originating the install. Used for funnel attribution.",
            "enum": [
              "lovable",
              "bolt",
              "v0",
              "replit",
              "emergent",
              "base44",
              "stackblitz",
              "cursor",
              "windsurf",
              "continue",
              "vscode",
              "mcp",
              "cursor-mcp",
              "claude-desktop",
              "claude-code",
              "windsurf-mcp",
              "continue-mcp",
              "cline",
              "chatgpt",
              "unknown"
            ],
            "type": "string"
          },
          "siteName": {
            "description": "Business/site name to seed defaults (e.g. companyName).",
            "maxLength": 120,
            "type": "string"
          },
          "siteUrl": {
            "description": "Website URL for branding + origin lock seeding",
            "type": "string"
          }
        },
        "required": [
          "module"
        ],
        "type": "object"
      },
      "InstantiateWorkflowTemplateDto": {
        "properties": {
          "activate": {
            "description": "Activate workflow immediately after creation",
            "type": "boolean"
          },
          "description": {
            "description": "Override description for the workflow",
            "type": "string"
          },
          "name": {
            "description": "Override name for the new workflow",
            "type": "string"
          },
          "variables": {
            "description": "Initial variable values for the template",
            "type": "object"
          }
        },
        "type": "object"
      },
      "InvoiceBrandingDto": {
        "properties": {
          "accentColor": {
            "example": "#1E40AF",
            "type": "string"
          },
          "address": {
            "example": "123 Main St, City, State 12345",
            "type": "string"
          },
          "companyName": {
            "example": "Your Company Name",
            "type": "string"
          },
          "email": {
            "example": "contact@company.com",
            "type": "string"
          },
          "footerText": {
            "example": "Thank you for your business!",
            "type": "string"
          },
          "logo": {
            "example": "https://example.com/logo.png",
            "type": "string"
          },
          "phone": {
            "example": "+1 (555) 123-4567",
            "type": "string"
          },
          "primaryColor": {
            "example": "#3B82F6",
            "type": "string"
          }
        },
        "required": [
          "companyName",
          "primaryColor",
          "accentColor",
          "footerText"
        ],
        "type": "object"
      },
      "InvoiceItemDto": {
        "properties": {
          "amount": {
            "example": 10000,
            "type": "number"
          },
          "description": {
            "example": "Item description",
            "type": "string"
          },
          "name": {
            "example": "Service Item",
            "type": "string"
          },
          "quantity": {
            "example": 1,
            "type": "number"
          },
          "taxRate": {
            "example": 0.1,
            "type": "number"
          }
        },
        "required": [
          "name",
          "description",
          "quantity",
          "amount"
        ],
        "type": "object"
      },
      "McpToolRequestDto": {
        "properties": {
          "arguments": {
            "description": "Tool arguments",
            "example": {
              "phone": "+15551234567",
              "script_id": "scr_hvac_v1",
              "session_type": "outbound"
            },
            "type": "object"
          },
          "metadata": {
            "description": "Request metadata",
            "example": {
              "context": "missed_call_recovery",
              "priority": "high"
            },
            "type": "object"
          },
          "tool": {
            "description": "Tool name (e.g., agents.start_call, leads.upsert)",
            "example": "agents.start_call",
            "type": "string"
          }
        },
        "required": [
          "tool",
          "arguments"
        ],
        "type": "object"
      },
      "McpToolResponseDto": {
        "properties": {
          "content": {
            "description": "Tool execution result",
            "example": {
              "call_id": "call_002",
              "call_session_id": "rts_456",
              "dial_status": "initiated"
            },
            "type": "object"
          },
          "error": {
            "description": "Error message if execution failed",
            "example": "Invalid phone number format",
            "type": "string"
          },
          "isError": {
            "description": "Whether the tool execution was successful",
            "example": true,
            "type": "boolean"
          },
          "metadata": {
            "description": "Execution metadata",
            "example": {
              "cached": false,
              "execution_time_ms": 150
            },
            "type": "object"
          }
        },
        "required": [
          "content",
          "isError"
        ],
        "type": "object"
      },
      "MergeCompaniesDto": {
        "properties": {
          "primaryId": {
            "example": "primary-company-id",
            "type": "string"
          },
          "secondaryIds": {
            "example": [
              "secondary-company-id-1",
              "secondary-company-id-2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "primaryId",
          "secondaryIds"
        ],
        "type": "object"
      },
      "PayoutScheduleDto": {
        "properties": {
          "delayDays": {
            "description": "Delay days for payouts",
            "example": "minimum",
            "type": "object"
          },
          "interval": {
            "enum": [
              "daily",
              "weekly",
              "monthly",
              "manual"
            ],
            "example": "daily",
            "type": "string"
          },
          "monthlyAnchor": {
            "description": "Day of the month for monthly payouts",
            "example": 15,
            "type": "number"
          },
          "weeklyAnchor": {
            "enum": [
              "monday",
              "tuesday",
              "wednesday",
              "thursday",
              "friday"
            ],
            "example": "monday",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PayoutSettingsDto": {
        "properties": {
          "debitNegativeBalances": {
            "example": true,
            "type": "boolean"
          },
          "schedule": {
            "$ref": "#/components/schemas/PayoutScheduleDto"
          },
          "statementDescriptor": {
            "example": "SERVICEAGENT",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PersonDto": {
        "properties": {
          "address": {
            "$ref": "#/components/schemas/AddressDto"
          },
          "dateOfBirth": {
            "$ref": "#/components/schemas/DateOfBirthDto"
          },
          "director": {
            "example": false,
            "type": "boolean"
          },
          "email": {
            "example": "jane@example.com",
            "type": "string"
          },
          "executive": {
            "example": true,
            "type": "boolean"
          },
          "firstName": {
            "example": "Jane",
            "type": "string"
          },
          "lastName": {
            "example": "Doe",
            "type": "string"
          },
          "ownershipPercentage": {
            "example": 100,
            "type": "number"
          },
          "phone": {
            "example": "+15125551234",
            "type": "string"
          },
          "ssnLast4": {
            "example": "1234",
            "type": "string"
          },
          "title": {
            "example": "CEO",
            "type": "string"
          },
          "verificationDocumentBack": {
            "description": "Stripe file ID for document back",
            "type": "string"
          },
          "verificationDocumentFront": {
            "description": "Stripe file ID for document front",
            "type": "string"
          }
        },
        "required": [
          "firstName",
          "lastName"
        ],
        "type": "object"
      },
      "PostCallRuleActionDto": {
        "properties": {
          "actionId": {
            "description": "Catalog action id",
            "type": "string"
          },
          "id": {
            "description": "Stable per-rule action identifier. Assign when the UI wants to preserve optimistic-update keys across saves; omit to let the backend generate one.",
            "type": "string"
          },
          "params": {
            "description": "Per-action parameters keyed by param id.",
            "type": "object"
          }
        },
        "required": [
          "actionId"
        ],
        "type": "object"
      },
      "PostCallRuleConditionDto": {
        "properties": {
          "id": {
            "description": "Catalog condition id",
            "type": "string"
          },
          "params": {
            "description": "Per-condition parameters keyed by param id.",
            "type": "object"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "PostCallRuleDto": {
        "properties": {
          "actions": {
            "items": {
              "$ref": "#/components/schemas/PostCallRuleActionDto"
            },
            "type": "array"
          },
          "condition": {
            "$ref": "#/components/schemas/PostCallRuleConditionDto"
          },
          "enabled": {
            "description": "When false, the rule exists but is paused. Defaults to true.",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "condition",
          "actions"
        ],
        "type": "object"
      },
      "PredictiveAnalyticsDto": {
        "properties": {
          "acquisitionCost": {
            "description": "Acquisition cost",
            "example": 5000,
            "type": "number"
          },
          "confidence": {
            "description": "Prediction confidence metrics",
            "example": {
              "dataPoints": 12,
              "lastUpdated": "2024-01-15T10:00:00Z",
              "overall": 85
            },
            "type": "object"
          },
          "contactId": {
            "description": "Contact ID",
            "example": "cm123456789",
            "type": "string"
          },
          "estimatedDealSize": {
            "description": "Estimated deal size",
            "example": 50000,
            "type": "number"
          },
          "lifetimeValue": {
            "description": "Lifetime value",
            "example": 150000,
            "type": "number"
          },
          "likelihoodToBuy": {
            "description": "Likelihood to buy (0-100)",
            "example": 75,
            "type": "number"
          },
          "nextMilestone": {
            "description": "Next milestone",
            "example": "Technical evaluation",
            "type": "string"
          },
          "optimalContactChannel": {
            "description": "Optimal contact channel",
            "example": "PHONE",
            "type": "string"
          },
          "optimalContactTime": {
            "description": "Optimal contact time",
            "example": "Tuesday 2-4 PM",
            "type": "string"
          },
          "predictedChurnDate": {
            "description": "Predicted churn date",
            "example": null,
            "type": "string"
          }
        },
        "required": [
          "contactId",
          "likelihoodToBuy",
          "estimatedDealSize",
          "optimalContactTime",
          "optimalContactChannel",
          "nextMilestone",
          "predictedChurnDate",
          "lifetimeValue",
          "acquisitionCost",
          "confidence"
        ],
        "type": "object"
      },
      "PreviewContactsImportDto": {
        "properties": {
          "customFieldMapping": {
            "description": "Optional mapping of CSV column index (0-based) to custom field key (e.g. {\"4\":\"lead_source\"})",
            "example": {
              "4": "lead_source",
              "5": "industry"
            },
            "type": "object"
          },
          "fileHandle": {
            "description": "Filestack handle returned from the analyze call",
            "example": "ABC123xyz",
            "type": "string"
          },
          "mapping": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContactsImportMappingDto"
              }
            ],
            "description": "Field-to-column mapping selected by the user"
          }
        },
        "required": [
          "fileHandle",
          "mapping"
        ],
        "type": "object"
      },
      "PreviewVoicePromptDto": {
        "properties": {
          "callType": {
            "description": "Optional call-type override for the base prompt stack.",
            "enum": [
              "support",
              "sales",
              "general"
            ],
            "type": "string"
          },
          "direction": {
            "default": "inbound",
            "description": "Preview the prompt as if the call were inbound or outbound.",
            "enum": [
              "inbound",
              "outbound"
            ],
            "type": "string"
          },
          "handlingProfileMode": {
            "description": "Optional handling-profile mode override for the preview session contract.",
            "enum": [
              "inbound_category",
              "neutral_outbound",
              "custom_campaign"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "PublishedSnapshotDto": {
        "properties": {
          "compiledHash": {
            "description": "Hash of the compiled prompt (content digest)",
            "type": "string"
          },
          "fullText": {
            "description": "Full compiled prompt text as published",
            "type": "string"
          },
          "scalars": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublishedSnapshotScalarsDto"
              }
            ],
            "description": "Scalar projection of the published config"
          },
          "sections": {
            "description": "Section-level breakdown of the compiled prompt",
            "items": {
              "$ref": "#/components/schemas/PublishedSnapshotSectionDto"
            },
            "type": "array"
          }
        },
        "required": [
          "compiledHash",
          "fullText",
          "sections",
          "scalars"
        ],
        "type": "object"
      },
      "PublishedSnapshotScalarsDto": {
        "properties": {
          "handlingProfileCategory": {
            "description": "Resolved handling profile category",
            "type": "string"
          },
          "initialGreetingText": {
            "description": "Initial greeting text as spoken",
            "type": "string"
          },
          "name": {
            "description": "Voice agent display name",
            "type": "string"
          },
          "systemPrompt": {
            "description": "Raw system prompt as published",
            "type": "string"
          },
          "transferNumber": {
            "description": "Configured transfer number",
            "type": "string"
          },
          "voiceId": {
            "description": "Selected voice id (provider:voice)",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PublishedSnapshotSectionDto": {
        "properties": {
          "id": {
            "description": "Stable section id (e.g. \"identity\", \"faqs\")",
            "type": "string"
          },
          "text": {
            "description": "Rendered section text at publish time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "text"
        ],
        "type": "object"
      },
      "PurchaseCreditsDto": {
        "properties": {
          "credits": {
            "description": "Number of credits to purchase",
            "example": 500,
            "type": "number"
          },
          "customerEmail": {
            "example": "owner@business.com",
            "type": "string"
          },
          "customerName": {
            "example": "Jane Owner",
            "type": "string"
          },
          "paymentMethod": {
            "example": "credit_card",
            "type": "string"
          },
          "paymentMethodId": {
            "example": "pm_1234567890",
            "type": "string"
          }
        },
        "required": [
          "credits"
        ],
        "type": "object"
      },
      "RecurrenceRuleDto": {
        "properties": {
          "count": {
            "description": "Total number of occurrences (including the original appointment). Mutually inclusive with `until`.",
            "example": 6,
            "maximum": 52,
            "minimum": 1,
            "type": "number"
          },
          "frequency": {
            "description": "How often the appointment should repeat. Lowercase variants are accepted and uppercased server-side.",
            "enum": [
              "DAILY",
              "WEEKLY",
              "MONTHLY"
            ],
            "example": "WEEKLY",
            "type": "string"
          },
          "interval": {
            "description": "Spacing between occurrences in `frequency` units (e.g. `interval: 2` with `frequency: WEEKLY` = every other week). Defaults to 1.",
            "example": 1,
            "maximum": 52,
            "minimum": 1,
            "type": "number"
          },
          "until": {
            "description": "ISO 8601 datetime after which no further occurrences are generated. The engine stops generating once the next end-time would exceed this.",
            "example": "2026-12-31T23:59:59Z",
            "type": "string"
          }
        },
        "required": [
          "frequency"
        ],
        "type": "object"
      },
      "RefineWorkflowWithAiDto": {
        "properties": {
          "context": {
            "$ref": "#/components/schemas/WorkflowAiGenerateContextDto"
          },
          "conversationHistory": {
            "items": {
              "$ref": "#/components/schemas/WorkflowAiConversationMessageDto"
            },
            "type": "array"
          },
          "currentWorkflow": {
            "$ref": "#/components/schemas/WorkflowGraphPayloadDto"
          },
          "refinement": {
            "example": "Also add an email reminder and skip if appointment is cancelled",
            "type": "string"
          }
        },
        "required": [
          "currentWorkflow",
          "refinement"
        ],
        "type": "object"
      },
      "ReplacePostCallRulesDto": {
        "properties": {
          "rules": {
            "description": "The full set of rules for this agent. Replaces any existing rules — this is a PUT, not a PATCH.",
            "items": {
              "$ref": "#/components/schemas/PostCallRuleDto"
            },
            "type": "array"
          }
        },
        "required": [
          "rules"
        ],
        "type": "object"
      },
      "RescheduleSurveyInvitationDto": {
        "properties": {
          "sendAt": {
            "description": "ISO timestamp for new send time",
            "type": "string"
          }
        },
        "required": [
          "sendAt"
        ],
        "type": "object"
      },
      "ResolveImportReviewDecisionDto": {
        "properties": {
          "action": {
            "enum": [
              "MERGE",
              "CREATE_NEW",
              "IGNORE"
            ],
            "type": "string"
          },
          "contactId": {
            "description": "Target contactId for MERGE action",
            "example": "cuid_contact_id",
            "type": "string"
          },
          "row": {
            "description": "CSV row number (as shown in preview)",
            "example": 12,
            "type": "number"
          }
        },
        "required": [
          "row",
          "action"
        ],
        "type": "object"
      },
      "ResolveImportReviewTaskDto": {
        "properties": {
          "closeTask": {
            "description": "If true, mark the review task DONE when all candidates are resolved.",
            "example": true,
            "type": "boolean"
          },
          "decisions": {
            "items": {
              "$ref": "#/components/schemas/ResolveImportReviewDecisionDto"
            },
            "type": "array"
          }
        },
        "required": [
          "decisions"
        ],
        "type": "object"
      },
      "RetryWorkflowRunDto": {
        "properties": {
          "baseDelaySeconds": {
            "description": "Override base backoff seconds",
            "example": 60,
            "type": "number"
          },
          "maxRetries": {
            "description": "Override max retries for this request",
            "example": 3,
            "type": "number"
          }
        },
        "type": "object"
      },
      "ReviewCommentDto": {
        "properties": {
          "authorId": {
            "example": "usr_123",
            "type": "string"
          },
          "body": {
            "example": "Called customer, offered re-service tomorrow.",
            "type": "string"
          },
          "createdAt": {
            "example": "2025-01-21T10:15:00.000Z",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "example": "mrc_123",
            "type": "string"
          },
          "metadata": {
            "example": {
              "channel": "phone"
            },
            "type": "object"
          },
          "reviewId": {
            "example": "mrev_123",
            "type": "string"
          },
          "updatedAt": {
            "example": "2025-01-21T10:30:00.000Z",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "reviewId",
          "authorId",
          "body",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "ReviewInboxItemDto": {
        "properties": {
          "assignedToId": {
            "example": "usr_123",
            "type": "string"
          },
          "authorName": {
            "example": "Jane Doe",
            "type": "string"
          },
          "authorUrl": {
            "example": "https://maps.google.com/?cid=123",
            "type": "string"
          },
          "body": {
            "example": "Technician arrived on time and fixed the issue quickly.",
            "type": "string"
          },
          "commentCount": {
            "example": 2,
            "type": "number"
          },
          "createdAt": {
            "example": "2025-01-21T10:15:00.000Z",
            "format": "date-time",
            "type": "string"
          },
          "externalReviewId": {
            "example": "accounts/123/locations/456/reviews/789",
            "type": "string"
          },
          "externalUrl": {
            "description": "Deep-link to the review on the platform if available (for manual reply flow)",
            "example": "https://www.yelp.com/biz/xyz#reviews",
            "type": "string"
          },
          "id": {
            "example": "mrev_123",
            "type": "string"
          },
          "lastViewedAt": {
            "example": "2025-12-24T12:34:56.000Z",
            "format": "date-time",
            "type": "string"
          },
          "listingConnectionId": {
            "example": "mlc_123",
            "type": "string"
          },
          "locationId": {
            "example": "loc_123",
            "type": "string"
          },
          "metadata": {
            "example": {
              "aiSuggestedReply": {
                "text": "..."
              }
            },
            "type": "object"
          },
          "postedAt": {
            "example": "2025-01-20T15:04:23.000Z",
            "format": "date-time",
            "type": "string"
          },
          "rating": {
            "example": 5,
            "type": "number"
          },
          "repliedAt": {
            "example": "2025-01-22T11:00:00.000Z",
            "format": "date-time",
            "type": "string"
          },
          "replyText": {
            "example": "Thank you for the great feedback!",
            "type": "string"
          },
          "reviewRequestId": {
            "example": "mrr_123",
            "type": "string"
          },
          "sentiment": {
            "enum": [
              "positive",
              "neutral",
              "negative"
            ],
            "example": "positive",
            "type": "string"
          },
          "source": {
            "example": "google",
            "type": "string"
          },
          "title": {
            "example": "Excellent service",
            "type": "string"
          },
          "updatedAt": {
            "example": "2025-01-21T10:30:00.000Z",
            "format": "date-time",
            "type": "string"
          },
          "workflowStatus": {
            "enum": [
              "new",
              "needs_response",
              "responded",
              "resolved"
            ],
            "example": "needs_response",
            "type": "string"
          }
        },
        "required": [
          "id",
          "source",
          "workflowStatus",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "ReviewProviderDto": {
        "properties": {
          "displayName": {
            "example": "Google",
            "type": "string"
          },
          "key": {
            "example": "google",
            "type": "string"
          },
          "supportsIngestion": {
            "description": "Whether we can ingest reviews via an integration connection",
            "type": "boolean"
          },
          "supportsManualReply": {
            "default": true,
            "description": "Whether manual reply flow is supported (copy/paste + deep-link)",
            "type": "boolean"
          },
          "supportsReplyPublishing": {
            "description": "Whether we can publish replies via API (if false, use manual reply flow)",
            "type": "boolean"
          }
        },
        "required": [
          "key",
          "displayName",
          "supportsIngestion",
          "supportsReplyPublishing",
          "supportsManualReply"
        ],
        "type": "object"
      },
      "ReviewRequestContactDto": {
        "properties": {
          "consentStatus": {
            "example": {
              "call": "unknown",
              "email": "unknown",
              "marketing": "unknown",
              "sms": "unknown"
            },
            "type": "object"
          },
          "email": {
            "example": "jane@example.com",
            "type": "string"
          },
          "firstName": {
            "example": "Jane",
            "type": "string"
          },
          "id": {
            "example": "contact_123",
            "type": "string"
          },
          "lastName": {
            "example": "Doe",
            "type": "string"
          },
          "phone": {
            "example": "15555550123",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "ReviewRequestLocationDto": {
        "properties": {
          "id": {
            "example": "loc_123",
            "type": "string"
          },
          "name": {
            "example": "Main Office",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "ReviewRequestMessageDto": {
        "properties": {
          "emailBody": {
            "example": "<p>We value your feedback...</p>",
            "type": "string"
          },
          "emailSubject": {
            "example": "How did we do?",
            "type": "string"
          },
          "reviewUrl": {
            "example": "https://example.com/review",
            "type": "string"
          },
          "smsBody": {
            "example": "Thanks for choosing us! Leave a review: https://example.com/review",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ReviewRequestResponseDto": {
        "properties": {
          "appointmentId": {
            "example": "appt_123",
            "type": "string"
          },
          "channel": {
            "enum": [
              "email",
              "sms"
            ],
            "example": "email",
            "type": "string"
          },
          "clickedAt": {
            "example": "2025-01-21T10:07:00.000Z",
            "type": "string"
          },
          "contact": {
            "$ref": "#/components/schemas/ReviewRequestContactDto"
          },
          "contactEmail": {
            "example": "jane@example.com",
            "type": "string"
          },
          "contactId": {
            "example": "contact_123",
            "type": "string"
          },
          "contactName": {
            "example": "Jane Doe",
            "type": "string"
          },
          "createdAt": {
            "example": "2025-01-21T09:55:00.000Z",
            "type": "string"
          },
          "errorMessage": {
            "example": "Contact does not have email address",
            "type": "string"
          },
          "id": {
            "example": "mrr_123",
            "type": "string"
          },
          "internalStatus": {
            "description": "Internal status (back-compat)",
            "enum": [
              "queued",
              "sending",
              "sent",
              "failed"
            ],
            "example": "queued",
            "type": "string"
          },
          "jobId": {
            "example": "job_123",
            "type": "string"
          },
          "location": {
            "$ref": "#/components/schemas/ReviewRequestLocationDto"
          },
          "locationId": {
            "example": "loc_123",
            "type": "string"
          },
          "metadata": {
            "example": {
              "settings": {
                "mode": "manual"
              }
            },
            "type": "object"
          },
          "openedAt": {
            "example": "2025-01-21T10:06:00.000Z",
            "type": "string"
          },
          "rating": {
            "example": 5,
            "type": "number"
          },
          "responseReceivedAt": {
            "example": "2025-01-22T12:00:00.000Z",
            "type": "string"
          },
          "responseStatus": {
            "example": "DELIVERED",
            "type": "string"
          },
          "reviewedAt": {
            "example": "2025-01-22T12:00:00.000Z",
            "type": "string"
          },
          "sendAfter": {
            "example": "2025-01-21T10:00:00.000Z",
            "type": "string"
          },
          "sentAt": {
            "example": "2025-01-21T10:05:00.000Z",
            "type": "string"
          },
          "specStatus": {
            "description": "Deprecated; use `status`",
            "enum": [
              "pending",
              "sent",
              "opened",
              "clicked",
              "reviewed",
              "failed"
            ],
            "example": "pending",
            "type": "string"
          },
          "status": {
            "description": "Spec status (Marketing Suite frontend)",
            "enum": [
              "pending",
              "sent",
              "opened",
              "clicked",
              "reviewed",
              "failed"
            ],
            "example": "pending",
            "type": "string"
          },
          "triggerType": {
            "example": "manual",
            "type": "string"
          },
          "updatedAt": {
            "example": "2025-01-21T09:55:00.000Z",
            "type": "string"
          }
        },
        "required": [
          "id",
          "channel",
          "status"
        ],
        "type": "object"
      },
      "ReviewSettingsDto": {
        "properties": {
          "autoTrigger": {
            "default": "appointment_completed",
            "enum": [
              "appointment_completed",
              "job_completed"
            ],
            "type": "string"
          },
          "autoTriggers": {
            "description": "Auto trigger toggles (spec field)",
            "example": {
              "afterAppointment": true,
              "afterInvoicePaid": false
            },
            "type": "object"
          },
          "channels": {
            "default": [
              "email"
            ],
            "items": {
              "enum": [
                "email",
                "sms"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "delayHours": {
            "description": "Delay before sending, in hours (spec field)",
            "example": 0,
            "type": "number"
          },
          "delayMinutes": {
            "description": "Delay before sending, in minutes",
            "example": 0,
            "type": "number"
          },
          "emailTemplateId": {
            "description": "Email template ID to use for review requests",
            "type": "string"
          },
          "fromEmail": {
            "description": "Fallback from-email address",
            "type": "string"
          },
          "fromPhone": {
            "description": "Fallback from-phone number in E.164 format",
            "type": "string"
          },
          "mode": {
            "default": "manual",
            "enum": [
              "manual",
              "auto"
            ],
            "type": "string"
          },
          "reviewUrl": {
            "description": "Primary review URL to include in messages",
            "type": "string"
          },
          "smsTemplateId": {
            "description": "SMS template ID or campaign identifier",
            "type": "string"
          },
          "template": {
            "description": "Default template (spec field)",
            "example": {
              "body": "<p>We value your feedback...</p>",
              "subject": "How did we do?"
            },
            "type": "object"
          }
        },
        "required": [
          "mode",
          "channels"
        ],
        "type": "object"
      },
      "ReviewTemplateOverrideDto": {
        "properties": {
          "body": {
            "example": "<p>We value your feedback...</p>",
            "type": "string"
          },
          "subject": {
            "example": "How did we do?",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SendBulkEmailDto": {
        "properties": {
          "bodyHtml": {
            "description": "Inline email body HTML (required when not using template)",
            "example": "<p>Special offer for {{contact.firstName}}</p>",
            "type": "string"
          },
          "filter": {
            "description": "Filter criteria for selecting recipients",
            "example": {
              "industry": "legal",
              "lastActivityDate": {
                "gte": "2024-01-01"
              }
            },
            "type": "object"
          },
          "recipientIds": {
            "description": "Array of contact IDs to send to",
            "example": [
              "contact-uuid-1",
              "contact-uuid-2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "subject": {
            "description": "Email subject with template variables (required when not using template)",
            "example": "{{contact.firstName}}, your property match",
            "type": "string"
          },
          "templateId": {
            "description": "Email template ID",
            "example": "template-uuid-123",
            "type": "string"
          },
          "trackClicks": {
            "default": true,
            "description": "Enable click tracking",
            "example": true,
            "type": "boolean"
          },
          "trackOpens": {
            "default": true,
            "description": "Enable open tracking",
            "example": true,
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "SendEmailDto": {
        "properties": {
          "attachmentIds": {
            "description": "Uploaded attachment IDs (e.g. Filestack handles).",
            "example": [
              "A1B2C3D4"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "attachmentUrls": {
            "description": "Uploaded attachment file URLs (e.g. Filestack CDN URLs)",
            "example": [
              "https://cdn.example.com/file.pdf"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "body": {
            "description": "Email body in HTML format",
            "example": "<h1>Hello {{contact.firstName}}</h1><p>This is your case update...</p>",
            "type": "string"
          },
          "bodyFormat": {
            "default": "markdown",
            "description": "Format of the provided body content",
            "enum": [
              "markdown",
              "plain",
              "html"
            ],
            "example": "markdown",
            "type": "string"
          },
          "campaignId": {
            "description": "Email campaign ID for tracking (optional)",
            "example": "campaign-uuid-123",
            "type": "string"
          },
          "companyId": {
            "description": "Company ID for tracking (optional)",
            "example": "company-uuid-123",
            "type": "string"
          },
          "contactId": {
            "description": "Contact ID for tracking (optional)",
            "example": "contact-uuid-123",
            "type": "string"
          },
          "dealId": {
            "description": "Deal ID for tracking (optional)",
            "example": "deal-uuid-123",
            "type": "string"
          },
          "sendAt": {
            "description": "Schedule email for future delivery (ISO 8601)",
            "example": "2025-10-20T10:00:00Z",
            "type": "string"
          },
          "subject": {
            "description": "Email subject",
            "example": "Your case update",
            "type": "string"
          },
          "templateId": {
            "description": "Email template ID (optional)",
            "example": "template-uuid-123",
            "type": "string"
          },
          "to": {
            "description": "Recipient email address",
            "example": "client@example.com",
            "type": "string"
          },
          "trackClicks": {
            "default": true,
            "description": "Enable click tracking",
            "example": true,
            "type": "boolean"
          },
          "trackOpens": {
            "default": true,
            "description": "Enable open tracking",
            "example": true,
            "type": "boolean"
          }
        },
        "required": [
          "to",
          "subject",
          "body"
        ],
        "type": "object"
      },
      "SendMagicLinkDto": {
        "properties": {
          "email": {
            "description": "Email address to send magic link to",
            "example": "customer@example.com",
            "type": "string"
          },
          "organizationId": {
            "description": "Optional organization ID to scope contact lookup",
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "type": "object"
      },
      "SendWidgetMessageDto": {
        "properties": {},
        "type": "object"
      },
      "SetLocationStaffDto": {
        "properties": {
          "primaryStaffId": {
            "description": "Optional staff ID or same-org user ID to mark as primary for this location",
            "example": "staff_1",
            "type": "string"
          },
          "staffIds": {
            "description": "Staff IDs, or same-org user IDs that should be promoted to staff, assigned to this location",
            "example": [
              "staff_1",
              "user_1"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "staffIds"
        ],
        "type": "object"
      },
      "SetWorkingHoursDto": {
        "properties": {
          "workingHours": {
            "items": {
              "$ref": "#/components/schemas/WorkingHourDto"
            },
            "type": "array"
          }
        },
        "required": [
          "workingHours"
        ],
        "type": "object"
      },
      "SettingsDto": {
        "properties": {
          "payouts": {
            "$ref": "#/components/schemas/PayoutSettingsDto"
          }
        },
        "type": "object"
      },
      "SuggestWorkflowDto": {
        "properties": {
          "industry": {
            "description": "Override the organization industry if needed",
            "example": "roofing",
            "type": "string"
          },
          "maxSuggestions": {
            "description": "Maximum number of workflow suggestions to return",
            "example": 3,
            "type": "number"
          },
          "prompt": {
            "description": "Natural language description of the business challenge",
            "example": "We need to automatically follow up with customers for Google reviews after HVAC service visits.",
            "type": "string"
          }
        },
        "required": [
          "prompt"
        ],
        "type": "object"
      },
      "SurveyQuestionInputDto": {
        "properties": {
          "logic": {
            "description": "Conditional logic for showing the question",
            "type": "object"
          },
          "options": {
            "description": "Question specific options or metadata (display, scale labels, etc.)",
            "type": "object"
          },
          "orderIndex": {
            "description": "Overrides default ordering (0-based)",
            "type": "number"
          },
          "required": {
            "default": false,
            "type": "boolean"
          },
          "subtitle": {
            "example": "0 = Not likely, 10 = Extremely likely",
            "type": "string"
          },
          "title": {
            "description": "Canonical question prompt. Use `title`; legacy `text` payloads are not part of the API contract.",
            "example": "How likely are you to recommend us?",
            "type": "string"
          },
          "type": {
            "enum": [
              "NPS_SCALE",
              "CSAT_STARS",
              "CSAT_THUMBS",
              "LIKERT",
              "MULTI_SELECT",
              "SINGLE_SELECT",
              "FREE_TEXT",
              "BOOLEAN"
            ],
            "example": "NPS_SCALE",
            "type": "string"
          }
        },
        "required": [
          "title",
          "type"
        ],
        "type": "object"
      },
      "SurveyQuestionResponseDto": {
        "properties": {
          "id": {
            "type": "string"
          },
          "logic": {
            "type": "object"
          },
          "options": {
            "type": "object"
          },
          "orderIndex": {
            "type": "number"
          },
          "required": {
            "default": false,
            "type": "boolean"
          },
          "subtitle": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "enum": [
              "NPS_SCALE",
              "CSAT_STARS",
              "CSAT_THUMBS",
              "LIKERT",
              "MULTI_SELECT",
              "SINGLE_SELECT",
              "FREE_TEXT",
              "BOOLEAN"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "type",
          "required",
          "orderIndex"
        ],
        "type": "object"
      },
      "SurveyTemplateListResponseDto": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/SurveyTemplateResponseDto"
            },
            "type": "array"
          },
          "limit": {
            "type": "number"
          },
          "meta": {
            "$ref": "#/components/schemas/SurveyTemplatePaginationMetaDto"
          },
          "page": {
            "type": "number"
          },
          "total": {
            "type": "number"
          },
          "totalPages": {
            "type": "number"
          }
        },
        "required": [
          "total",
          "page",
          "limit",
          "totalPages",
          "data",
          "meta"
        ],
        "type": "object"
      },
      "SurveyTemplatePaginationMetaDto": {
        "properties": {
          "limit": {
            "type": "number"
          },
          "page": {
            "type": "number"
          },
          "total": {
            "type": "number"
          },
          "totalPages": {
            "type": "number"
          }
        },
        "required": [
          "total",
          "page",
          "limit",
          "totalPages"
        ],
        "type": "object"
      },
      "SurveyTemplateResponseDto": {
        "properties": {
          "channels": {
            "items": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "createdByUserId": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "isActive": {
            "default": true,
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "organizationId": {
            "type": "string"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/SurveyQuestionResponseDto"
            },
            "type": "array"
          },
          "scoreType": {
            "enum": [
              "NPS",
              "CSAT",
              "CES",
              "CUSTOM"
            ],
            "type": "string"
          },
          "theme": {
            "type": "object"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "createdAt",
          "updatedAt",
          "organizationId",
          "name",
          "scoreType",
          "channels",
          "isActive",
          "questions"
        ],
        "type": "object"
      },
      "TestCallStatusResponseDto": {
        "properties": {
          "callId": {
            "type": "string"
          },
          "duration": {
            "description": "Duration in seconds (when completed).",
            "type": "number"
          },
          "startedAt": {
            "type": "string"
          },
          "status": {
            "enum": [
              "initiating",
              "ringing",
              "connected",
              "completed",
              "failed"
            ],
            "type": "string"
          }
        },
        "required": [
          "callId",
          "status"
        ],
        "type": "object"
      },
      "TosAcceptanceDto": {
        "properties": {
          "date": {
            "example": 1732945923,
            "type": "number"
          },
          "ip": {
            "example": "203.0.113.42",
            "type": "string"
          },
          "userAgent": {
            "example": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
            "type": "string"
          }
        },
        "type": "object"
      },
      "TransferAppointmentDto": {
        "properties": {
          "reason": {
            "description": "Reason for transfer (stored in audit trail)",
            "type": "string"
          },
          "toLocationId": {
            "description": "Destination location ID",
            "type": "string"
          }
        },
        "required": [
          "toLocationId"
        ],
        "type": "object"
      },
      "TransferDealDto": {
        "properties": {
          "reason": {
            "description": "Reason for transfer (stored in audit trail)",
            "type": "string"
          },
          "toLocationId": {
            "description": "Destination location ID",
            "type": "string"
          }
        },
        "required": [
          "toLocationId"
        ],
        "type": "object"
      },
      "TriggerReviewIngestDto": {
        "properties": {
          "connectionId": {
            "description": "Specific listing connection to ingest reviews for",
            "example": "mlc_123",
            "type": "string"
          },
          "since": {
            "description": "Only ingest reviews posted after this ISO timestamp",
            "example": "2025-01-01T00:00:00.000Z",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateActivityDto": {
        "properties": {
          "body": {
            "description": "Activity description/body",
            "example": "Discussed project requirements and timeline",
            "type": "string"
          },
          "callId": {
            "description": "Related call ID",
            "example": "call_abc",
            "type": "string"
          },
          "companyId": {
            "description": "Related company ID",
            "example": "company_456",
            "type": "string"
          },
          "contactId": {
            "description": "Related contact ID",
            "example": "contact_123",
            "type": "string"
          },
          "customJson": {
            "description": "Custom JSON data",
            "example": "{\"customField\": \"value\"}",
            "type": "object"
          },
          "dealId": {
            "description": "Related deal ID",
            "example": "deal_789",
            "type": "string"
          },
          "durationSec": {
            "description": "Duration in seconds",
            "example": 1800,
            "type": "number"
          },
          "messageId": {
            "description": "Related message ID",
            "example": "message_def",
            "type": "string"
          },
          "ownerId": {
            "description": "Activity owner ID",
            "example": "user_123",
            "type": "string"
          },
          "subject": {
            "description": "Activity subject/title",
            "example": "Follow-up call with John Doe",
            "type": "string"
          },
          "type": {
            "description": "Type of activity",
            "enum": [
              "CALL",
              "EMAIL",
              "SMS",
              "MEETING",
              "NOTE",
              "REVIEW_REQUEST",
              "QUOTE_SENT",
              "PAYMENT_RECEIVED"
            ],
            "example": "CALL",
            "type": "string"
          },
          "whenAt": {
            "description": "When the activity occurred or is scheduled",
            "example": "2024-01-15T10:00:00Z",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateAgentDto": {
        "properties": {
          "capabilities": {
            "description": "Capabilities of the AI agent",
            "example": [
              "crm_lookup",
              "kb_search",
              "appointment_booking"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "description": {
            "description": "Description of the AI agent",
            "example": "Handles customer inquiries and support requests",
            "type": "string"
          },
          "isActive": {
            "default": true,
            "description": "Whether the agent is active",
            "example": true,
            "type": "boolean"
          },
          "maxTokens": {
            "default": 4000,
            "description": "Maximum tokens for AI responses",
            "example": 4000,
            "maximum": 8000,
            "minimum": 100,
            "type": "number"
          },
          "model": {
            "default": "gpt-4",
            "description": "AI model to use",
            "example": "gpt-4",
            "type": "string"
          },
          "name": {
            "description": "Name of the AI agent",
            "example": "Customer Service Agent",
            "type": "string"
          },
          "systemPrompt": {
            "description": "System prompt for the AI agent",
            "example": "You are a helpful customer service assistant...",
            "type": "string"
          },
          "temperature": {
            "default": 0.7,
            "description": "Temperature for AI responses (0-1)",
            "example": 0.7,
            "maximum": 1,
            "minimum": 0,
            "type": "number"
          }
        },
        "type": "object"
      },
      "UpdateAppointmentDto": {
        "properties": {
          "bufferAfterMinutes": {
            "description": "Minutes of buffer time after the appointment",
            "example": 15,
            "type": "number"
          },
          "bufferBeforeMinutes": {
            "description": "Minutes of buffer time before the appointment",
            "example": 15,
            "type": "number"
          },
          "customJson": {
            "additionalProperties": true,
            "description": "Free-form metadata blob attached to the appointment (e.g. partner-specific tags, internal notes). The server stores this passthrough — schema is intentionally open-ended so workflows and integrations can stash whatever they need.",
            "example": {
              "internalNotes": "VIP customer",
              "priority": "high"
            },
            "type": "object"
          },
          "customerEmail": {
            "description": "Required when `customerId` is not provided. Server upserts a `Contact` by email when this path is taken. Ignored when `customerId` is set.",
            "example": "jane@example.com",
            "type": "string"
          },
          "customerId": {
            "description": "Optional: pass the FK of an existing CRM `Contact` to attach the appointment without an email upsert. When provided, `customerName` and `customerEmail` are not required (and are ignored if sent — the contact row is the source of truth). When omitted, the public/inline booking path runs and `customerName` + `customerEmail` are required.",
            "example": "cnt_123",
            "type": "string"
          },
          "customerName": {
            "description": "Required when `customerId` is not provided. Ignored when `customerId` is set.",
            "example": "Jane Smith",
            "type": "string"
          },
          "customerPhone": {
            "example": "+1234567890",
            "type": "string"
          },
          "description": {
            "example": "Please clean the kitchen thoroughly",
            "type": "string"
          },
          "duration": {
            "description": "Duration in minutes. Used to derive endAt when it is omitted.",
            "example": 90,
            "type": "number"
          },
          "endAt": {
            "example": "2024-01-15T12:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "locationId": {
            "description": "Location ID for this appointment (multi-location)",
            "example": "loc_123",
            "type": "string"
          },
          "notes": {
            "example": "Customer prefers morning appointment",
            "type": "string"
          },
          "ownerId": {
            "example": "user-id",
            "type": "string"
          },
          "recurrenceRule": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RecurrenceRuleDto"
              }
            ],
            "description": "Recurrence rule describing how this appointment should repeat"
          },
          "resourceIds": {
            "description": "Resource IDs required for this appointment (rooms/equipment/vehicles)",
            "example": [
              "res_123"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "scheduledAt": {
            "description": "Legacy alias for startAt (ISO 8601).",
            "example": "2024-01-15T10:00:00Z",
            "type": "string"
          },
          "serviceId": {
            "description": "Optional. Defaults to the first active service offering when omitted.",
            "example": "service-id",
            "type": "string"
          },
          "serviceOfferingId": {
            "description": "Alias for serviceId kept for backward compatibility.",
            "example": "service-offering-id",
            "type": "string"
          },
          "staffId": {
            "description": "Optional. Defaults to the first active staff member when omitted.",
            "example": "staff-id",
            "type": "string"
          },
          "startAt": {
            "example": "2024-01-15T10:00:00Z",
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "example": "scheduled",
            "type": "string"
          },
          "title": {
            "example": "House Cleaning Service",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateBusinessProfileDto": {
        "properties": {
          "about": {
            "type": "string"
          },
          "contact": {
            "type": "object"
          },
          "faqs": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "pricebook": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "services": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "websiteUrl": {
            "type": "string"
          },
          "workingHours": {
            "type": "object"
          }
        },
        "type": "object"
      },
      "UpdateChannelConfigDto": {
        "properties": {},
        "type": "object"
      },
      "UpdateCompanyDto": {
        "properties": {
          "address": {
            "example": "123 Main St",
            "type": "string"
          },
          "addressJson": {
            "example": {
              "city": "Anytown",
              "state": "CA",
              "street": "123 Main St",
              "zip": "12345"
            },
            "type": "object"
          },
          "customJson": {
            "example": {
              "customField": "value"
            },
            "type": "object"
          },
          "domain": {
            "example": "acme.com",
            "type": "string"
          },
          "industry": {
            "example": "Technology",
            "type": "string"
          },
          "name": {
            "example": "Acme Corporation",
            "type": "string"
          },
          "phone": {
            "example": "+1234567890",
            "type": "string"
          },
          "size": {
            "example": "50-100",
            "type": "string"
          },
          "tags": {
            "example": [
              "tag1",
              "tag2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "website": {
            "example": "https://acme.com",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateContactDto": {
        "properties": {
          "behavioralProfile": {
            "description": "Behavioral intelligence profile",
            "example": {
              "communicationStyle": "FORMAL",
              "decisionMakingStyle": "ANALYTICAL",
              "engagementFrequency": "WEEKLY",
              "engagementScore": 75,
              "lastEngagementAt": "2024-01-15T10:00:00Z",
              "preferredChannel": "EMAIL",
              "responseRate": 80,
              "riskTolerance": "MEDIUM",
              "urgencyPreference": "HIGH"
            },
            "type": "object"
          },
          "companyId": {
            "example": "company-id",
            "type": "string"
          },
          "contextualProfile": {
            "description": "Contextual intelligence profile",
            "example": {
              "budgetRange": "50K_100K",
              "challenges": [
                "Legacy systems"
              ],
              "companySize": "MEDIUM",
              "competitors": [
                "Competitor A",
                "Competitor B"
              ],
              "currentSolutions": [
                "Current solution X"
              ],
              "decisionTimeline": "3_MONTHS",
              "goals": [
                "Increase efficiency",
                "Reduce costs"
              ],
              "industry": "Technology",
              "painPoints": [
                "Integration challenges",
                "Cost concerns"
              ],
              "successMetrics": [
                "ROI",
                "User adoption"
              ]
            },
            "type": "object"
          },
          "customJson": {
            "example": {
              "customField": "value"
            },
            "type": "object"
          },
          "email": {
            "example": "john.doe@example.com",
            "type": "string"
          },
          "firstName": {
            "example": "John",
            "type": "string"
          },
          "identityProfile": {
            "description": "Enhanced identity information",
            "example": {
              "avatar": "https://example.com/avatar.jpg",
              "department": "Sales",
              "language": "en",
              "preferredName": "Johnny",
              "role": "Decision Maker",
              "seniority": "SENIOR",
              "socialProfiles": [],
              "timezone": "America/New_York",
              "title": "VP of Sales"
            },
            "type": "object"
          },
          "lastName": {
            "example": "Doe",
            "type": "string"
          },
          "leadScore": {
            "description": "Explicit lead score override. If omitted the system auto-calculates.",
            "example": 65,
            "type": "number"
          },
          "lifecycleStageId": {
            "description": "Lifecycle stage identifier.",
            "example": "stage_cuid",
            "type": "string"
          },
          "lifecycleStageKey": {
            "description": "Lifecycle stage key (e.g., MQL, SQL). Takes precedence over lifecycleStageId.",
            "example": "SQL",
            "type": "string"
          },
          "ownerId": {
            "example": "user-id",
            "type": "string"
          },
          "phone": {
            "example": "+1234567890",
            "type": "string"
          },
          "predictiveProfile": {
            "description": "Predictive intelligence profile",
            "example": {
              "acquisitionCost": 5000,
              "estimatedDealSize": 50000,
              "lifetimeValue": 150000,
              "likelihoodToBuy": 75,
              "nextBestAction": "Schedule demo call",
              "nextMilestone": "Technical evaluation",
              "optimalContactChannel": "PHONE",
              "optimalContactTime": "Tuesday 2-4 PM",
              "predictedChurnDate": null
            },
            "type": "object"
          },
          "relationshipProfile": {
            "description": "Relationship intelligence profile",
            "example": {
              "churnRisk": 20,
              "influenceLevel": "HIGH",
              "loyaltyScore": 80,
              "networkConnections": [],
              "referralPotential": 70,
              "relationshipStage": "WARM",
              "relationshipStrength": 85
            },
            "type": "object"
          },
          "status": {
            "example": "LEAD",
            "type": "string"
          },
          "tags": {
            "example": [
              "tag1",
              "tag2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "UpdateDealDto": {
        "properties": {
          "amountCents": {
            "example": 250000,
            "type": "number"
          },
          "closeDate": {
            "example": "2025-12-31",
            "type": "string"
          },
          "companyId": {
            "example": "comp_123",
            "type": "string"
          },
          "contactId": {
            "example": "contact_123",
            "type": "string"
          },
          "currency": {
            "example": "USD",
            "type": "string"
          },
          "ownerId": {
            "example": "user_123",
            "type": "string"
          },
          "pipelineId": {
            "example": "pipe_123",
            "type": "string"
          },
          "source": {
            "example": "inbound",
            "type": "string"
          },
          "stage": {
            "description": "Deprecated alias for stageId. Will be coerced into stageId if provided.",
            "example": "stage_legacy",
            "type": "string"
          },
          "stageId": {
            "example": "stage_123",
            "type": "string"
          },
          "status": {
            "enum": [
              "OPEN",
              "WON",
              "LOST"
            ],
            "example": "OPEN",
            "type": "string"
          },
          "title": {
            "example": "New Website Project",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateEmailTemplateDto": {
        "properties": {
          "body": {
            "description": "Alias for bodyHtml",
            "example": "<html>...</html>",
            "type": "string"
          },
          "bodyHtml": {
            "description": "Email body in HTML format with template variables",
            "example": "<h2>Proposal Follow-up</h2><p>Dear {{contact.firstName}},</p><p>I wanted to follow up on the proposal...</p>",
            "type": "string"
          },
          "category": {
            "description": "Template category",
            "example": "sales",
            "type": "string"
          },
          "isActive": {
            "description": "Whether the template is active",
            "example": true,
            "type": "boolean"
          },
          "name": {
            "description": "Template name",
            "example": "Proposal Follow-up",
            "type": "string"
          },
          "subject": {
            "description": "Email subject with template variables",
            "example": "Follow-up: {{proposal.title}}",
            "type": "string"
          },
          "variables": {
            "description": "Array of template variables used",
            "example": [
              "contact.firstName",
              "proposal.title",
              "user.name"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "UpdateKbArticleDto": {
        "properties": {
          "aiAgentId": {
            "example": "cleaning",
            "type": "string"
          },
          "category": {
            "example": "pricing",
            "type": "string"
          },
          "content": {
            "example": "Our standard service includes cleaning, maintenance, and repair work...",
            "type": "string"
          },
          "fileHandles": {
            "description": "Filestack file handles for attachments",
            "example": [
              "handle1",
              "handle2"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tags": {
            "example": [
              "pricing",
              "services",
              "costs"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "example": "Service Pricing Information",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateLifecycleStageDto": {
        "properties": {
          "allowedNextStageIds": {
            "example": [
              "stage_sql",
              "stage_customer"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "defaultAssignmentRuleId": {
            "example": "rule_cuid",
            "type": "string"
          },
          "description": {
            "example": "On-site or virtual estimate booked",
            "type": "string"
          },
          "entryCriteriaJson": {
            "description": "JSON criteria (stringified) for auto entry",
            "type": "string"
          },
          "exitCriteriaJson": {
            "description": "JSON criteria (stringified) for auto exit",
            "type": "string"
          },
          "isDefault": {
            "example": true,
            "type": "boolean"
          },
          "name": {
            "example": "Estimate Scheduled",
            "type": "string"
          },
          "order": {
            "example": 2,
            "type": "number"
          },
          "probability": {
            "description": "Probability of closing from this stage (0-100)",
            "example": 60,
            "type": "number"
          }
        },
        "type": "object"
      },
      "UpdateLocationDto": {
        "properties": {
          "address": {
            "description": "Primary address of the location",
            "example": "123 Main St, Dallas, TX 75201",
            "type": "string"
          },
          "addressJson": {
            "description": "Structured address object (optional). Useful for maps + formatting.",
            "example": {
              "city": "Dallas",
              "country": "US",
              "state": "TX",
              "street": "123 Main St",
              "zip": "75201"
            },
            "type": "object"
          },
          "googlePlaceId": {
            "description": "Google Place ID for this location (optional).",
            "example": "ChIJN1t_tDeuEmsRUsoyG83frY4",
            "type": "string"
          },
          "isActive": {
            "description": "Whether the location is active",
            "example": true,
            "type": "boolean"
          },
          "latitude": {
            "description": "Latitude (optional)",
            "example": 32.7767,
            "type": "number"
          },
          "longitude": {
            "description": "Longitude (optional)",
            "example": -96.797,
            "type": "number"
          },
          "marketingNapOverride": {
            "description": "Location-specific override for listings NAP data",
            "example": {
              "address": {
                "city": "Dallas",
                "state": "TX",
                "street": "123 Main St",
                "zip": "75201"
              },
              "name": "Acme Heating & Air - Downtown",
              "phone": "+1-555-0123"
            },
            "type": "object"
          },
          "name": {
            "description": "Display name for the location",
            "example": "Downtown Office",
            "type": "string"
          },
          "phone": {
            "description": "Contact phone number for the location",
            "example": "+1-555-0123",
            "type": "string"
          },
          "serviceAreaZipCodes": {
            "description": "Zip codes served by this location for localized marketing",
            "example": [
              "75201",
              "75202",
              "75001"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "timezone": {
            "description": "Timezone identifier for scheduling and availability",
            "example": "America/Chicago",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateReviewReplyDto": {
        "properties": {
          "replyText": {
            "example": "Thanks for the feedback! We are reaching out to schedule a follow-up visit.",
            "type": "string"
          }
        },
        "required": [
          "replyText"
        ],
        "type": "object"
      },
      "UpdateReviewSettingsDto": {
        "properties": {
          "autoTrigger": {
            "default": "appointment_completed",
            "enum": [
              "appointment_completed",
              "job_completed"
            ],
            "type": "string"
          },
          "autoTriggers": {
            "description": "Auto triggers (spec field)",
            "example": {
              "afterAppointment": true,
              "afterInvoicePaid": false
            },
            "type": "object"
          },
          "channels": {
            "items": {
              "enum": [
                "email",
                "sms"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "delayHours": {
            "description": "Delay before sending, in hours (spec field)",
            "example": 24,
            "type": "number"
          },
          "delayMinutes": {
            "description": "Delay before sending, in minutes",
            "example": 0,
            "type": "number"
          },
          "emailTemplateId": {
            "description": "Email template ID to use for review requests",
            "type": "string"
          },
          "fromEmail": {
            "description": "Fallback from-email address",
            "type": "string"
          },
          "fromPhone": {
            "description": "Fallback from-phone number in E.164 format",
            "type": "string"
          },
          "locationId": {
            "description": "Location override for settings",
            "type": "string"
          },
          "mode": {
            "default": "manual",
            "enum": [
              "manual",
              "auto"
            ],
            "type": "string"
          },
          "reviewUrl": {
            "description": "Primary review URL to include in messages",
            "type": "string"
          },
          "smsTemplateId": {
            "description": "SMS template ID or campaign identifier",
            "type": "string"
          },
          "template": {
            "description": "Default template (spec field)",
            "example": {
              "body": "<p>We value your feedback...</p>",
              "subject": "How did we do?"
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "UpdateReviewWorkflowDto": {
        "properties": {
          "assignedToId": {
            "description": "Assign to user id. Use null to unassign.",
            "example": "usr_123",
            "type": "string"
          },
          "workflowStatus": {
            "enum": [
              "new",
              "needs_response",
              "responded",
              "resolved"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateSavedFilterDto": {
        "properties": {
          "criteria": {
            "description": "Filter criteria object using the same keys as list endpoints",
            "example": {
              "status": "inactive",
              "tags": [
                "needs-follow-up"
              ]
            },
            "type": "object"
          },
          "isFavorite": {
            "example": true,
            "type": "boolean"
          },
          "name": {
            "example": "Updated Name",
            "maxLength": 100,
            "minLength": 1,
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateStaffDto": {
        "properties": {
          "bio": {
            "example": "Experienced HVAC technician with 10+ years",
            "type": "string"
          },
          "calendarId": {
            "example": "google-calendar-id",
            "type": "string"
          },
          "isActive": {
            "example": true,
            "type": "boolean"
          },
          "skills": {
            "example": [
              "hvac",
              "maintenance",
              "repair"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "example": "Senior Technician",
            "type": "string"
          },
          "userId": {
            "example": "user-id",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateSurveyCampaignDto": {
        "properties": {
          "channelStrategy": {
            "description": "Channel sequencing, review thresholds, etc.",
            "type": "object"
          },
          "cooldownDays": {
            "description": "Days before the same contact can receive this campaign again",
            "example": 30,
            "type": "number"
          },
          "defaultDelayMinutes": {
            "description": "Delay in minutes before sending invitations",
            "example": 120,
            "type": "number"
          },
          "name": {
            "example": "Post-appointment follow-up",
            "type": "string"
          },
          "status": {
            "example": "paused",
            "type": "string"
          },
          "targetFilters": {
            "description": "Targeting filters (services, staff, tags, etc.)",
            "type": "object"
          },
          "templateId": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateSurveyFrontendDto": {
        "properties": {
          "description": {
            "type": "string"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/FrontendSurveyQuestionDto"
            },
            "type": "array"
          },
          "settings": {
            "type": "object"
          },
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateSurveyTemplateDto": {
        "properties": {
          "channels": {
            "example": [
              "EMAIL",
              "SMS"
            ],
            "items": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "description": {
            "example": "Sent 2 hours after appointment completion",
            "type": "string"
          },
          "name": {
            "example": "Post-Appointment NPS",
            "type": "string"
          },
          "questions": {
            "description": "Ordered list of questions to display",
            "items": {
              "$ref": "#/components/schemas/SurveyQuestionInputDto"
            },
            "type": "array"
          },
          "scoreType": {
            "enum": [
              "NPS",
              "CSAT",
              "CES",
              "CUSTOM"
            ],
            "example": "NPS",
            "type": "string"
          },
          "theme": {
            "description": "Custom theme (colors, fonts, etc.)",
            "type": "object"
          }
        },
        "type": "object"
      },
      "UpdateSurveyTemplateStatusDto": {
        "properties": {
          "isActive": {
            "example": true,
            "type": "boolean"
          }
        },
        "required": [
          "isActive"
        ],
        "type": "object"
      },
      "UpdateSurveyTriggerDto": {
        "properties": {
          "delayMinutes": {
            "description": "Delay in minutes before sending invitations",
            "example": 120,
            "type": "number"
          },
          "entityFilters": {
            "description": "Filters for matching events (serviceIds, staffIds, etc.)",
            "type": "object"
          },
          "isActive": {
            "default": true,
            "type": "boolean"
          },
          "type": {
            "enum": [
              "APPOINTMENT_COMPLETED",
              "TICKET_RESOLVED",
              "CALL_COMPLETED",
              "CHAT_ENDED",
              "WORKFLOW_NODE",
              "MANUAL"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateTaskDto": {
        "properties": {
          "companyId": {
            "description": "Related company ID",
            "example": "company_456",
            "type": "string"
          },
          "contactId": {
            "description": "Related contact ID",
            "example": "contact_123",
            "type": "string"
          },
          "customJson": {
            "description": "Custom JSON data",
            "example": "{\"customField\": \"value\"}",
            "type": "object"
          },
          "dealId": {
            "description": "Related deal ID",
            "example": "deal_789",
            "type": "string"
          },
          "description": {
            "description": "Task description",
            "example": "Call client to discuss project timeline",
            "type": "string"
          },
          "dueAt": {
            "description": "Task due date",
            "example": "2024-01-15T17:00:00Z",
            "type": "string"
          },
          "estimatedHours": {
            "description": "Estimated hours for this task",
            "example": 2.5,
            "type": "number"
          },
          "ownerId": {
            "description": "Task owner ID",
            "example": "user_123",
            "type": "string"
          },
          "phaseId": {
            "description": "Related project phase ID",
            "example": "phase_456",
            "type": "string"
          },
          "priority": {
            "description": "Task priority",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ],
            "example": "HIGH",
            "type": "string"
          },
          "projectId": {
            "description": "Related project ID",
            "example": "project_123",
            "type": "string"
          },
          "stage": {
            "description": "Task stage (e.g., todo, in_progress, review, done)",
            "example": "todo",
            "type": "string"
          },
          "status": {
            "description": "Task status",
            "enum": [
              "OPEN",
              "DONE"
            ],
            "example": "DONE",
            "type": "string"
          },
          "title": {
            "description": "Task title",
            "example": "Follow up with client",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateTimeOffDto": {
        "properties": {
          "endDate": {
            "example": "2025-02-05",
            "type": "string"
          },
          "reason": {
            "example": "Family vacation",
            "type": "string"
          },
          "startDate": {
            "example": "2025-02-01",
            "type": "string"
          },
          "type": {
            "default": "OTHER",
            "enum": [
              "VACATION",
              "SICK",
              "PERSONAL",
              "OTHER"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateUnifiedAgentDto": {
        "properties": {},
        "type": "object"
      },
      "UpdateWebhookDto": {
        "properties": {
          "events": {
            "description": "List of events to subscribe to",
            "example": [
              "company.created",
              "contact.updated",
              "deal.won"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "secret": {
            "description": "Custom webhook secret (auto-generated if not provided)",
            "example": "whsec_your_webhook_secret_here",
            "type": "string"
          },
          "url": {
            "example": "https://api.example.com/webhooks",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateWidgetReadDto": {
        "properties": {},
        "type": "object"
      },
      "UpdateWidgetTypingDto": {
        "properties": {},
        "type": "object"
      },
      "UpdateWorkflowDto": {
        "properties": {
          "definition": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowDefinitionDto"
              }
            ],
            "deprecated": true,
            "description": "Builder-shaped graph wrapper. The server lifts `definition.nodes` / `definition.edges` onto the root before validation. Prefer sending `nodes` / `edges` at the root directly."
          },
          "description": {
            "example": "Automates the customer onboarding process",
            "type": "string"
          },
          "edges": {
            "description": "Workflow graph edges. Edges referencing unknown nodes are dropped server-side rather than 400ing the save.",
            "items": {
              "$ref": "#/components/schemas/WorkflowEdgeDto"
            },
            "type": "array"
          },
          "isActive": {
            "example": true,
            "type": "boolean"
          },
          "locationId": {
            "description": "Multi-location v1: optional locationId. If omitted, defaults to the active location (X-Location-Id) when present; otherwise creates a global default.",
            "nullable": true,
            "type": "string"
          },
          "metadata": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowMetadataDto"
              }
            ],
            "description": "Workflow metadata including AI conversation history and builder source tags."
          },
          "name": {
            "example": "New Customer Onboarding",
            "type": "string"
          },
          "nodes": {
            "description": "Workflow graph nodes. Sparse/null entries emitted by the builder during edits are tolerated and stripped server-side.",
            "items": {
              "$ref": "#/components/schemas/WorkflowNodeDto"
            },
            "type": "array"
          },
          "trigger": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowTriggerDto"
              }
            ],
            "description": "Trigger object for quick-start templates (type + config)."
          },
          "triggerConfig": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowTriggerConfigDto"
              }
            ],
            "description": "Trigger configuration scoped to `triggerType`. Cron schedule for SCHEDULED, event filter for EVENT, webhook secret for WEBHOOK, ignored for MANUAL."
          },
          "triggerType": {
            "enum": [
              "MANUAL",
              "SCHEDULED",
              "EVENT",
              "WEBHOOK"
            ],
            "example": "MANUAL",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UploadKnowledgeDocumentDto": {
        "properties": {
          "fileName": {
            "description": "Optional original file name",
            "example": "pricing.xlsx",
            "type": "string"
          },
          "fileUrl": {
            "description": "File URL (for file uploads like pdf/docx/xlsx) – e.g. Filestack/S3 URL.",
            "type": "string"
          },
          "mimeType": {
            "description": "Optional file MIME type (helps extraction when remote servers send octet-stream)",
            "example": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            "type": "string"
          },
          "name": {
            "description": "Display name for the document.",
            "example": "Refund Policy",
            "type": "string"
          },
          "size": {
            "description": "Optional size in bytes",
            "example": 123456,
            "type": "number"
          },
          "text": {
            "description": "Plain text content (for type=txt).",
            "type": "string"
          },
          "type": {
            "description": "Document type. \"document\" is an alias accepted from the Documents tab and is resolved to a concrete extension (pdf/doc/docx/...) from fileName/mimeType server-side.",
            "enum": [
              "txt",
              "url",
              "pdf",
              "doc",
              "docx",
              "rtf",
              "md",
              "xls",
              "xlsx",
              "notion",
              "document"
            ],
            "example": "url",
            "type": "string"
          },
          "url": {
            "description": "URL (for type=url or notion).",
            "example": "https://example.com/refunds",
            "type": "string"
          }
        },
        "required": [
          "name",
          "type"
        ],
        "type": "object"
      },
      "UploadWidgetAttachmentDto": {
        "properties": {},
        "type": "object"
      },
      "UpsertVoiceAgentConfigDto": {
        "properties": {
          "businessKeywords": {
            "description": "Operator-curated business keywords. These are brand / product / competitor names and industry jargon the caller is likely to say — the kind of proper nouns that generic STT models mis-segment. Fed to both the STT keyword-boost layer (Deepgram lane) and the post-STT keyword-repair layer (all lanes). Each entry 3–60 chars, max 25 total.",
            "example": [
              "JustCall",
              "ServiceAgent",
              "HVAC",
              "Nest thermostat",
              "Bellevue"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "callPurpose": {
            "description": "Concrete reason for outbound calls made by this agent. Short declarative sentence/fragment (\"calling to invite Gaurav to demo ServiceAgent\", \"confirming the 3pm Tuesday appointment\"). Drives the peer-AI mode first-turn statement AND adds a per-turn reminder on outbound calls so the LLM pushes toward a concrete objective instead of drifting into discovery questions. Send empty string to clear. Ignored on inbound calls.",
            "example": "calling to invite you to demo ServiceAgent",
            "maxLength": 500,
            "type": "string"
          },
          "handlingProfile": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VoiceHandlingProfileDto"
              }
            ],
            "description": "Structured AIVA handling profile used to derive category-specific runtime behavior."
          },
          "httpActions": {
            "description": "Operator-authored HTTP actions. Each entry materializes into a per-call `http_<id>` tool the LLM can invoke mid-call. Use this to wire AIVA to your own CRM, ticketing, or inventory APIs without writing TypeScript. Include the `http` scope in `toolScopes` to enable the category.",
            "items": {
              "$ref": "#/components/schemas/VoiceAgentHttpActionDto"
            },
            "type": "array"
          },
          "language": {
            "default": "en-US",
            "description": "BCP-47 language tag",
            "type": "string"
          },
          "name": {
            "description": "Display name for this voice agent",
            "maxLength": 120,
            "type": "string"
          },
          "personaTemplateId": {
            "description": "ID of the persona template this agent was created from (see `GET /v1/agents/persona-templates`). Purely for analytics — which templates convert best, which ones operators start from most often. Never read at runtime. Persisted into `VoiceAgent.configJson.personaTemplateId`. Set on agent creation and left untouched on subsequent edits.",
            "example": "outbound-sales-sdr",
            "maxLength": 100,
            "type": "string"
          },
          "provider": {
            "default": "aiva",
            "description": "Voice runtime provider",
            "enum": [
              "aiva"
            ],
            "type": "string"
          },
          "systemPrompt": {
            "description": "System prompt for voice agent",
            "type": "string"
          },
          "toolScopes": {
            "description": "Allowed tool scopes for this agent",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "voiceId": {
            "description": "Voice ID (provider-specific)",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ValidateWorkflowWithAiDto": {
        "properties": {
          "workflow": {
            "$ref": "#/components/schemas/WorkflowGraphPayloadDto"
          }
        },
        "required": [
          "workflow"
        ],
        "type": "object"
      },
      "VerifyMagicLinkDto": {
        "properties": {
          "token": {
            "description": "Magic link token from URL",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "type": "object"
      },
      "VoiceAgentHttpActionAuthDto": {
        "properties": {
          "headerName": {
            "type": "string"
          },
          "secret": {
            "type": "string"
          },
          "token": {
            "type": "string"
          },
          "type": {
            "enum": [
              "none",
              "bearer",
              "hmac_sha256"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "VoiceAgentHttpActionDto": {
        "properties": {
          "auth": {
            "$ref": "#/components/schemas/VoiceAgentHttpActionAuthDto"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "description": "Short id, alphanumeric + underscore. Becomes `http_<id>` in the LLM tool list.",
            "type": "string"
          },
          "maxResponseBytes": {
            "maximum": 16384,
            "minimum": 256,
            "type": "number"
          },
          "method": {
            "enum": [
              "GET",
              "POST",
              "PUT",
              "PATCH",
              "DELETE"
            ],
            "type": "string"
          },
          "mutatesState": {
            "type": "boolean"
          },
          "parameters": {
            "description": "JSON schema object describing the LLM-provided args.",
            "type": "object"
          },
          "requiresConfirmation": {
            "type": "boolean"
          },
          "responseKeys": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "timeoutMs": {
            "maximum": 8000,
            "minimum": 250,
            "type": "number"
          },
          "url": {
            "description": "Fully-qualified https:// URL.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "VoiceConfigDryRunDto": {
        "properties": {
          "history": {
            "description": "Prior conversation turns, oldest first. Omit for the first turn. Max 20 turns.",
            "items": {
              "$ref": "#/components/schemas/VoiceConfigDryRunHistoryMessageDto"
            },
            "type": "array"
          },
          "message": {
            "description": "The message to send as the current user turn. For the first turn of a rehearsal, this is whatever the simulated caller said first.",
            "maxLength": 2000,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "message"
        ],
        "type": "object"
      },
      "VoiceConfigDryRunHistoryMessageDto": {
        "properties": {
          "content": {
            "type": "string"
          },
          "role": {
            "enum": [
              "user",
              "assistant"
            ],
            "type": "string"
          }
        },
        "required": [
          "role",
          "content"
        ],
        "type": "object"
      },
      "VoiceHandlingProfileDto": {
        "properties": {
          "afterHoursMode": {
            "enum": [
              "capture",
              "route",
              "emergency_triage"
            ],
            "type": "string"
          },
          "category": {
            "description": "Canonical AIVA handling category. Alias values are accepted and normalized server-side.",
            "enum": [
              "general",
              "roofing",
              "hvac",
              "plumbing",
              "electrical",
              "solar",
              "garage",
              "legal",
              "insurance",
              "medical",
              "automotive",
              "realestate",
              "salon",
              "fitness",
              "restaurant",
              "dental",
              "spa",
              "home_services",
              "consulting",
              "cleaning",
              "landscaping",
              "painting",
              "seo_services",
              "marketing_agency",
              "advertising_agency"
            ],
            "type": "string"
          },
          "multiLocation": {
            "type": "boolean"
          },
          "schedulingMode": {
            "enum": [
              "none",
              "lead_capture_only",
              "booking_enabled"
            ],
            "type": "string"
          },
          "serviceAreaMode": {
            "enum": [
              "single_location",
              "multi_location",
              "territory_based"
            ],
            "type": "string"
          },
          "transferMode": {
            "enum": [
              "never",
              "on_request",
              "qualified_only",
              "always_for_emergency"
            ],
            "type": "string"
          },
          "useCase": {
            "enum": [
              "reception",
              "support",
              "sales",
              "dispatch",
              "booking",
              "intake"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "WebhookEndpointCreateResponseDto": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "events": {
            "description": "Event names this endpoint subscribes to (e.g. [\"appointment.booked\"]).",
            "example": [
              "appointment.booked",
              "appointment.cancelled"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "isActive": {
            "type": "boolean"
          },
          "lastUsedAt": {
            "description": "When this endpoint last received an event delivery attempt.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "organizationId": {
            "format": "uuid",
            "type": "string"
          },
          "secret": {
            "description": "Plaintext webhook signing secret. **Returned exactly once on create.** Subsequent reads expose only `secretLast4`. Store it securely; rotate by `POST /webhooks/endpoints/:id/test` flow if it leaks.",
            "type": "string"
          },
          "secretLast4": {
            "description": "Last 4 characters of the webhook signing secret. Use this for \"ends in xxxx\" UI indicators. The full secret is only returned on the original create response — copy it then or rotate.",
            "example": "a3f9",
            "nullable": true,
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          },
          "url": {
            "example": "https://example.com/webhook",
            "type": "string"
          }
        },
        "required": [
          "id",
          "organizationId",
          "url",
          "events",
          "isActive",
          "secretLast4",
          "createdAt",
          "updatedAt",
          "secret"
        ],
        "type": "object"
      },
      "WebhookEndpointResponseDto": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "events": {
            "description": "Event names this endpoint subscribes to (e.g. [\"appointment.booked\"]).",
            "example": [
              "appointment.booked",
              "appointment.cancelled"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "isActive": {
            "type": "boolean"
          },
          "lastUsedAt": {
            "description": "When this endpoint last received an event delivery attempt.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "organizationId": {
            "format": "uuid",
            "type": "string"
          },
          "secretLast4": {
            "description": "Last 4 characters of the webhook signing secret. Use this for \"ends in xxxx\" UI indicators. The full secret is only returned on the original create response — copy it then or rotate.",
            "example": "a3f9",
            "nullable": true,
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          },
          "url": {
            "example": "https://example.com/webhook",
            "type": "string"
          }
        },
        "required": [
          "id",
          "organizationId",
          "url",
          "events",
          "isActive",
          "secretLast4",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "WorkflowAiConversationMessageDto": {
        "properties": {
          "content": {
            "type": "string"
          },
          "role": {
            "enum": [
              "user",
              "assistant"
            ],
            "type": "string"
          }
        },
        "required": [
          "role",
          "content"
        ],
        "type": "object"
      },
      "WorkflowAiGenerateContextDto": {
        "properties": {
          "availableTemplates": {
            "description": "Template IDs available to the org/user context",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "existingWorkflows": {
            "description": "Optional list of existing workflows to reduce duplicates",
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "orgHasChannels": {
            "description": "Connected channels for the org (e.g. sms, email)",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "WorkflowDefinitionDto": {
        "properties": {
          "edges": {
            "items": {
              "$ref": "#/components/schemas/WorkflowEdgeDto"
            },
            "type": "array"
          },
          "nodes": {
            "items": {
              "$ref": "#/components/schemas/WorkflowNodeDto"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "WorkflowDryRunAsUserDto": {
        "properties": {
          "role": {
            "description": "Optional role override for permission-sensitive dry-run branches. This is simulation metadata only and never changes real permissions.",
            "example": "MANAGER",
            "type": "string"
          },
          "userId": {
            "description": "Optional user id to simulate as. Must belong to the current organization. When omitted, the current authenticated user is used.",
            "example": "user_123",
            "type": "string"
          }
        },
        "type": "object"
      },
      "WorkflowDryRunDto": {
        "properties": {
          "allowInactive": {
            "description": "When true, disabled workflows can be dry-run. Defaults to true because dry-run is an editor/testing surface and has no side effects.",
            "example": true,
            "type": "boolean"
          },
          "asUser": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowDryRunAsUserDto"
              }
            ],
            "description": "Simulate workflow context as a specific user/role. Server validates userId is in the current org and injects user context into triggerData.asUser."
          },
          "triggerData": {
            "description": "Synthetic trigger payload used by trigger/condition nodes during the dry run.",
            "example": {
              "ticket": {
                "id": "ticket_1",
                "priority": "high"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "WorkflowEdgeDto": {
        "properties": {
          "id": {
            "description": "Edge identifier. Auto-generated as `edge_<n>` server-side when omitted.",
            "example": "edge_1",
            "type": "string"
          },
          "source": {
            "description": "Source node id. Edges are dropped at validate-time if they reference an unknown node.",
            "example": "trigger_1",
            "type": "string"
          },
          "sourceHandle": {
            "description": "Output handle on the source node. Used by branching nodes (router/condition) to direct flow to a specific output.",
            "example": "high_intent",
            "type": "string"
          },
          "target": {
            "description": "Target node id. Edges are dropped at validate-time if they reference an unknown node.",
            "example": "send_sms_1",
            "type": "string"
          },
          "targetHandle": {
            "description": "Input handle on the target node. Rarely used; defaults to the node's only input.",
            "example": "in",
            "type": "string"
          }
        },
        "required": [
          "source",
          "target"
        ],
        "type": "object"
      },
      "WorkflowGraphPayloadDto": {
        "properties": {
          "description": {
            "type": "string"
          },
          "edges": {
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "nodes": {
            "items": {
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "name",
          "nodes",
          "edges"
        ],
        "type": "object"
      },
      "WorkflowMetadataDto": {
        "properties": {
          "aiConversationId": {
            "description": "AI builder conversation id that produced this workflow, when applicable.",
            "type": "string"
          },
          "extra": {
            "additionalProperties": true,
            "description": "Free-form passthrough fields. Anything the builder or future integrations need to round-trip without a contract change goes here.",
            "type": "object"
          },
          "source": {
            "description": "Source of the workflow (`builder`, `template:<id>`, `ai_suggested`, etc.). Used for analytics and to skip re-onboarding flows.",
            "example": "template:onboarding",
            "type": "string"
          }
        },
        "type": "object"
      },
      "WorkflowNodeDto": {
        "properties": {
          "config": {
            "additionalProperties": true,
            "description": "Per-node configuration consumed by the runtime engine. Schema varies by `type` — `trigger` nodes carry `triggerType`, action nodes carry channel-specific settings, etc.",
            "example": {
              "eventType": "appointment.booked",
              "triggerType": "EVENT"
            },
            "type": "object"
          },
          "data": {
            "additionalProperties": true,
            "description": "Builder-only UI metadata (icon, palette group, draft state). Not consumed by the runtime engine.",
            "example": {
              "uiType": "trigger.event"
            },
            "type": "object"
          },
          "id": {
            "description": "Stable identifier referenced by edges. Auto-generated by the builder if absent.",
            "example": "trigger_1",
            "type": "string"
          },
          "label": {
            "description": "Human-readable label shown on the canvas. Some templates use `name` as an alias.",
            "example": "Appointment Booked",
            "type": "string"
          },
          "name": {
            "description": "Legacy alias of `label` used by older template configs. The server treats `name` and `label` as interchangeable.",
            "example": "Appointment Booked",
            "type": "string"
          },
          "position": {
            "$ref": "#/components/schemas/WorkflowNodePositionDto"
          },
          "type": {
            "description": "Node type slug (e.g. `trigger`, `delay`, `condition`, `action.send_sms`). The runtime engine routes on this.",
            "example": "trigger",
            "type": "string"
          }
        },
        "required": [
          "id",
          "type"
        ],
        "type": "object"
      },
      "WorkflowNodePositionDto": {
        "properties": {
          "x": {
            "example": 240,
            "type": "number"
          },
          "y": {
            "example": 80,
            "type": "number"
          }
        },
        "required": [
          "x",
          "y"
        ],
        "type": "object"
      },
      "WorkflowTemplateInputDto": {
        "properties": {
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "edges": {
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "id": {
            "type": "string"
          },
          "industry": {
            "type": "string"
          },
          "metadata": {
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "nodes": {
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "tags": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "triggers": {
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "variables": {
            "items": {
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "industry",
          "category",
          "nodes",
          "edges"
        ],
        "type": "object"
      },
      "WorkflowTriggerConfigDto": {
        "properties": {
          "eventType": {
            "description": "Event topic for `triggerType: EVENT` workflows. The event taxonomy lives in `src/events/event-types.ts`.",
            "example": "appointment.booked",
            "type": "string"
          },
          "schedule": {
            "description": "Cron schedule for `triggerType: SCHEDULED` workflows. Standard 5-field UNIX cron syntax.",
            "example": "0 9 * * 1",
            "type": "string"
          },
          "timezone": {
            "description": "IANA timezone the cron schedule is interpreted in. Defaults to the org timezone when omitted.",
            "example": "America/New_York",
            "type": "string"
          },
          "webhook": {
            "additionalProperties": true,
            "description": "Webhook secret / verification config for `triggerType: WEBHOOK` workflows. Schema varies by integration.",
            "type": "object"
          }
        },
        "type": "object"
      },
      "WorkflowTriggerDto": {
        "properties": {
          "config": {
            "additionalProperties": true,
            "description": "Event-specific filter/configuration consumed by the trigger.",
            "type": "object"
          },
          "type": {
            "description": "Event topic this workflow should fire on (for templates without a graph trigger node).",
            "example": "appointment.scheduled",
            "type": "string"
          }
        },
        "required": [
          "type"
        ],
        "type": "object"
      },
      "WorkingHourDto": {
        "properties": {
          "dayOfWeek": {
            "example": 1,
            "maximum": 6,
            "minimum": 0,
            "type": "number"
          },
          "endTime": {
            "example": "17:00",
            "type": "string"
          },
          "isAvailable": {
            "default": true,
            "example": true,
            "type": "boolean"
          },
          "startTime": {
            "example": "09:00",
            "type": "string"
          }
        },
        "required": [
          "dayOfWeek",
          "startTime",
          "endTime",
          "isAvailable"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "IdempotencyKey": {
        "in": "header",
        "name": "Idempotency-Key",
        "type": "apiKey"
      },
      "OrgId": {
        "in": "header",
        "name": "x-org-id",
        "type": "apiKey"
      },
      "bearer": {
        "bearerFormat": "JWT",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "Curated public OpenAPI reference for ServiceAgent installs, widgets, CRM, scheduling, agents, knowledge, inbox, integrations, workflows, payments, webhooks, MCP, and voice operations. The complete backend contract is maintained separately as openapi.json.",
    "title": "ServiceAgent Public API",
    "version": "1.0",
    "x-source": "Generated from root openapi.json by scripts/build-public-openapi.js"
  },
  "openapi": "3.0.0",
  "paths": {
    "/v1/activities": {
      "get": {
        "description": "Lists activities scoped to the current organization. Optional filters support pagination and limiting to related records.",
        "operationId": "ActivitiesController_findAll",
        "parameters": [
          {
            "description": "Filter by activity type (e.g., CALL, MEETING, NOTE).",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict results to a specific contact.",
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict results to a specific company.",
            "in": "query",
            "name": "companyId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict results to a specific deal.",
            "in": "query",
            "name": "dealId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict results to tasks owned by a specific teammate.",
            "in": "query",
            "name": "ownerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum records to return. Defaults to service-level pagination.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Records to skip before collecting results.",
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Activities retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all activities",
        "tags": [
          "CRM Activities"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Creates a CRM activity for the current organization. Activities can be linked to contacts, companies, deals, and owners.",
        "operationId": "ActivitiesController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateActivityDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Activity created successfully"
          },
          "400": {
            "description": "Invalid input data"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new activity",
        "tags": [
          "CRM Activities"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/activities/{id}": {
      "delete": {
        "description": "Permanently removes an activity. Use with caution as this operation is irreversible.",
        "operationId": "ActivitiesController_remove",
        "parameters": [
          {
            "description": "Activity identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Activity deleted successfully"
          },
          "404": {
            "description": "Activity not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete activity",
        "tags": [
          "CRM Activities"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "description": "Retrieves a single activity including its relationships. Returns 404 when the activity does not belong to the organization.",
        "operationId": "ActivitiesController_findOne",
        "parameters": [
          {
            "description": "Activity identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Activity retrieved successfully"
          },
          "404": {
            "description": "Activity not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get activity by ID",
        "tags": [
          "CRM Activities"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Updates mutable fields for an existing activity. Use this to change status, details, or related entities.",
        "operationId": "ActivitiesController_update",
        "parameters": [
          {
            "description": "Activity identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateActivityDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Activity updated successfully"
          },
          "404": {
            "description": "Activity not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update activity",
        "tags": [
          "CRM Activities"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents": {
      "get": {
        "operationId": "UnifiedAgentsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List unified agents",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "UnifiedAgentsController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUnifiedAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a unified agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/persona-templates": {
      "get": {
        "operationId": "PersonaTemplatesController_list",
        "parameters": [
          {
            "description": "inbound | outbound | both",
            "in": "query",
            "name": "direction",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by category",
            "in": "query",
            "name": "category",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Array of persona templates with prompts, greetings, and placeholders"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List persona templates available for voice agent creation",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/persona-templates/{id}": {
      "get": {
        "operationId": "PersonaTemplatesController_get",
        "parameters": [
          {
            "description": "Template id, e.g. \"outbound-sales-sdr\"",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested template"
          },
          "404": {
            "description": "Template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch one persona template by id",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/post-call-rules/catalog": {
      "get": {
        "description": "Returns conditions + actions + integration status. Conditions are the 'IF' half of a rule (e.g. booking_confirmed). Actions are the 'THEN' half (e.g. send_sms). Each action indicates which integration it requires; the `integrations` block tells the UI which integrations the org already has connected so it can render inline setup prompts for the missing ones.",
        "operationId": "VoiceAgentConfigController_getPostCallRulesCatalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the post-call rules catalog for the rules editor",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/post-call-rules/templates": {
      "get": {
        "description": "Hand-curated 'recipes' the operator UI renders as a Recipes gallery — pick one, optionally tweak, then PUT into /post-call-rules. Each template includes condition + action params with sensible defaults, plus presentation metadata (label, icon, rationale, recommendedVerticals) for the gallery card.",
        "operationId": "VoiceAgentConfigController_getPostCallRuleTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List pre-curated post-call rule templates",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/post-call-rules/templates/{templateId}/apply-to-org": {
      "post": {
        "description": "Server-side instantiation for the Recipes tab. Applies a template by id to selected unified agents (or all agents when applyToAll=true). mode=append preserves existing rules; mode=replace overwrites target rule sets.",
        "operationId": "VoiceAgentConfigController_applyPostCallRuleTemplateToOrg",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyPostCallRuleTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Apply a post-call rule template to one or more agents",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/tool-catalog": {
      "get": {
        "description": "Returns every built-in voice tool with technical name, operator-facing display metadata, section grouping, and integration dependencies. Frontend renders the tool-selection UI entirely from this response — never hardcoded.",
        "operationId": "VoiceAgentConfigController_listToolCatalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the tool catalog for operator tool-scope UI",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/unified/{id}": {
      "delete": {
        "description": "Compatibility route for clients still calling DELETE /v1/agents/unified/:id. Prefer DELETE /v1/agents/:id.",
        "operationId": "UnifiedAgentsController_removeUnifiedAlias",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Legacy alias: delete a unified agent (soft delete)",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/voice-configs": {
      "get": {
        "description": "This route exists to prevent /agents/voice-configs from being captured by /agents/:id. Prefer GET /v1/agents/:id/voice-config.",
        "operationId": "UnifiedAgentsController_legacyVoiceConfigs",
        "parameters": [
          {
            "in": "query",
            "name": "agentId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "unifiedAgentId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Legacy alias for voice config lookup (compat: GET /v1/agents/voice-configs?agentId=...)",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}": {
      "delete": {
        "operationId": "UnifiedAgentsController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a unified agent (soft delete)",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "UnifiedAgentsController_get",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a unified agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "UnifiedAgentsController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUnifiedAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a unified agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/analytics": {
      "get": {
        "description": "Returns call performance metrics for the agent. (Best-effort based on stored call records.)",
        "operationId": "UnifiedAgentsController_analytics",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "timeRange",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get agent analytics",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/channels/chat/disable": {
      "post": {
        "operationId": "UnifiedAgentsController_disableChat",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disable chat channel for an agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/channels/chat/enable": {
      "post": {
        "operationId": "UnifiedAgentsController_enableChat",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnableChatChannelDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enable chat channel for an agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/channels/voice/disable": {
      "post": {
        "operationId": "UnifiedAgentsController_disableVoice",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disable voice channel for an agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/channels/voice/enable": {
      "post": {
        "operationId": "UnifiedAgentsController_enableVoice",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnableVoiceChannelDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enable voice channel for an agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/channels/{channel}": {
      "put": {
        "operationId": "UnifiedAgentsController_updateChannel",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "channel",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChannelConfigDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a channel configuration",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/post-call-rule-executions": {
      "get": {
        "description": "Returns `{ callId, executions: [{ ruleId, matched, skipReason?, actions: [{ actionId, status, output?, error? }] }] }` for one call. Main driver: the 'why didn't my rule fire?' debugging affordance in the operator UI.",
        "operationId": "VoiceAgentConfigController_getPostCallRuleExecutions",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The call id to inspect.",
            "in": "query",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a call's post-call rule execution log",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/post-call-rules": {
      "get": {
        "description": "Returns the stored rules as canonical objects. Rules authored against an older catalog version are dropped silently on read — the UI should re-show the editor so operators can re-author affected rules.",
        "operationId": "VoiceAgentConfigController_listPostCallRules",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List post-call rules for a voice agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "description": "Replaces the entire rule set — this is a PUT, not a PATCH. Intentional: rule lists are small (max 25), and atomic replacement avoids merge ambiguity when operators reorder / delete rules in the UI. Each rule's condition + action + params are validated against the catalog; invalid references return a 400 with a specific error (e.g. `rule 2 action 1: unknown action \"foo\"`).",
        "operationId": "VoiceAgentConfigController_replacePostCallRules",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplacePostCallRulesDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace post-call rules for a voice agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/publish": {
      "post": {
        "description": "Marks the agent as published and performs best-effort validation/synchronization for enabled channels.",
        "operationId": "UnifiedAgentsController_publish",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish an agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/sample-run": {
      "post": {
        "description": "Simulates a first-run voice-agent demo without phone provisioning, payments, or any external telephony side effects.",
        "operationId": "UnifiedAgentsController_runSampleCall",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sample call simulation completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Run a deterministic voice agent sample call",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/sample-runs/{runId}": {
      "get": {
        "operationId": "UnifiedAgentsController_getSampleCall",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sample call result retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch a deterministic voice agent sample-call result",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/sync-knowledge": {
      "post": {
        "operationId": "UnifiedAgentsController_syncKnowledge",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sync knowledge base to enabled channels",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/test-call": {
      "post": {
        "description": "Starts an outbound call using the agent’s voice configuration. Intended for pre-launch testing.",
        "operationId": "AgentTestCallsController_initiate",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InitiateTestCallDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestCallStatusResponseDto"
                }
              }
            },
            "description": ""
          },
          "400": {
            "description": "Bad request - agent not configured or invalid phone number"
          },
          "402": {
            "description": "Insufficient credits"
          },
          "404": {
            "description": "Agent not found"
          },
          "429": {
            "description": "Rate limited - too many concurrent calls"
          },
          "503": {
            "description": "Voice provider unavailable"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Initiate a test call to the user’s phone",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/test-call/{callId}": {
      "get": {
        "description": "Returns the latest status for a previously started test call. Uses the call record stored in DB.",
        "operationId": "AgentTestCallsController_status",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestCallStatusResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get test call status",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/test-call/{callId}/end": {
      "post": {
        "description": "Attempts to end an ongoing call via the voice provider. Always marks the call as ended in DB.",
        "operationId": "AgentTestCallsController_end",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Call ended"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "End an ongoing test call (best effort)",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config": {
      "get": {
        "operationId": "VoiceAgentConfigController_getVoiceConfig",
        "parameters": [
          {
            "description": "Unified agent ID",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Voice config returned"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get voice agent config for a unified agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "VoiceAgentConfigController_upsertVoiceConfig",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertVoiceAgentConfigDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create or update voice agent config for a unified agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config/dry-run": {
      "post": {
        "description": "Runs the LLM one turn with the current draft config — compiled system prompt, allowed tools, FAQs, handling profile — and returns what AIVA would say plus any tools it would call. No audio, no phone call, no tool execution. Operators use this to iterate on prompts + tool descriptions in seconds instead of placing a real test call for every change.",
        "operationId": "VoiceAgentConfigController_dryRunVoiceConfig",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoiceConfigDryRunDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The simulated assistant reply and tool invocations."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Test Drive: rehearse a single turn against the agent config",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config/prompt-preview": {
      "post": {
        "description": "Returns the compiled voice prompt, section metadata, cache boundary information, and planned runtime-context sections so frontend can render a prompt breakdown without starting a live call.",
        "operationId": "VoiceAgentConfigController_previewVoicePrompt",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewVoicePromptDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Inspect the compiled AIVA voice prompt for a unified agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config/publish": {
      "post": {
        "description": "Validates publish-readiness before promoting draft to published. Use ?force=true (OWNER/ADMIN only) to publish despite outstanding blockers; this path is logged.",
        "operationId": "VoiceAgentConfigController_publishVoiceConfig",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "When true, publish even if readiness blockers are reported. Logged for audit.",
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish voice agent config",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config/publish-preview": {
      "get": {
        "description": "Returns a single payload with the current readiness report and a human-readable summary of what will be published (voice, greeting, FAQs, knowledge bases, transfer settings, tools). Safe to render directly in the editor publish modal.",
        "operationId": "VoiceAgentConfigController_getVoiceConfigPublishPreview",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Customer-facing publish preview summary",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config/published-snapshot": {
      "get": {
        "description": "Returns the prompt, sections, and scalar projection captured at the most recent successful publish. Used by the \"Draft vs. Live\" diff panel. 404 when the agent has never been published.",
        "operationId": "VoiceAgentConfigController_getPublishedSnapshot",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get the last published prompt snapshot for this agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Called by the editor immediately after a successful publish to record the baseline used by the \"Draft vs. Live\" diff panel. Idempotent via the Idempotency-Key header.",
        "operationId": "VoiceAgentConfigController_upsertPublishedSnapshot",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishedSnapshotDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upsert the published prompt snapshot baseline",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/agents/{id}/voice-config/readiness": {
      "get": {
        "description": "Returns structured readiness issues (blockers, warnings, info) so the editor can show \"what must be fixed\" before publishing and \"what to double-check\".",
        "operationId": "VoiceAgentConfigController_getVoiceConfigReadiness",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get publish-readiness report for a unified agent voice config",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/agents": {
      "get": {
        "operationId": "AgentsController_findAll",
        "parameters": [
          {
            "in": "query",
            "name": "industry",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/AgentResponseDto"
                  },
                  "type": "array"
                }
              }
            },
            "description": "Agents retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all AI agents for the organization",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "AgentsController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentResponseDto"
                }
              }
            },
            "description": "Agent created successfully"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new AI agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/agents/templates/{industry}": {
      "get": {
        "operationId": "AgentsController_getTemplates",
        "parameters": [
          {
            "in": "path",
            "name": "industry",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get industry-specific agent templates",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/agents/{id}": {
      "delete": {
        "operationId": "AgentsController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent deleted successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden - insufficient permissions"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete an AI agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "AgentsController_findOne",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentResponseDto"
                }
              }
            },
            "description": "Agent retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a specific AI agent by ID",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "AgentsController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentResponseDto"
                }
              }
            },
            "description": "Agent updated successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update an AI agent",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/agents/{id}/calls": {
      "get": {
        "operationId": "AIAgentExtensionsController_getAgentCallHistory",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Call history retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "AI agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get AI agent call history",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/agents/{id}/performance": {
      "get": {
        "operationId": "AIAgentExtensionsController_getAgentPerformance",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Performance metrics retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "AI agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get AI agent performance metrics",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/agents/{id}/test": {
      "post": {
        "operationId": "AgentsController_testAgent",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent test completed successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Test an AI agent with sample input",
        "tags": [
          "AI Agents"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/brain/context": {
      "get": {
        "operationId": "AIBrainController_getContext",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "about": {
                      "type": "string"
                    },
                    "businessName": {
                      "type": "string"
                    },
                    "contact": {
                      "type": "object"
                    },
                    "faqs": {
                      "type": "array"
                    },
                    "lastSyncedAt": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "services": {
                      "type": "array"
                    },
                    "workingHours": {
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "AI Brain context retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get AI Brain context for chat/voice",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/brain/knowledge/search": {
      "post": {
        "operationId": "AIBrainController_searchKnowledge",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "results": {
                      "items": {
                        "properties": {
                          "category": {
                            "type": "string"
                          },
                          "citations": {
                            "type": "array"
                          },
                          "content": {
                            "type": "string"
                          },
                          "id": {
                            "type": "string"
                          },
                          "privacyLevel": {
                            "type": "string"
                          },
                          "relevance": {
                            "type": "number"
                          },
                          "searchMethod": {
                            "enum": [
                              "summary",
                              "chunk"
                            ],
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "searchMethod": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Knowledge search completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Search knowledge base with hybrid summary + chunk results",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/brain/profile": {
      "get": {
        "operationId": "AIBrainController_getProfile",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "about": {
                      "type": "string"
                    },
                    "contacts": {
                      "type": "object"
                    },
                    "coverageScore": {
                      "type": "number"
                    },
                    "faqs": {
                      "type": "array"
                    },
                    "lastSyncAt": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "pricebook": {
                      "type": "array"
                    },
                    "services": {
                      "type": "array"
                    },
                    "websiteUrl": {
                      "type": "string"
                    },
                    "workingHours": {
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Business profile retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get business profile with coverage metrics",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "AIBrainController_updateProfile",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBusinessProfileDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "coverageScore": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    },
                    "syncStartedAt": {
                      "format": "date-time",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Profile updated and sync initiated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update business profile and trigger AI sync",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/brain/profile/gaps": {
      "get": {
        "operationId": "AIBrainController_getProfileGaps",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "coverageScore": {
                      "type": "number"
                    },
                    "suggestions": {
                      "items": {
                        "properties": {
                          "field": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "severity": {
                            "enum": [
                              "high",
                              "medium",
                              "low"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Profile gaps analysis completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Analyze profile and return improvement suggestions",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/brain/profile/sync": {
      "post": {
        "operationId": "AIBrainController_syncProfile",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "estimatedCompletionSec": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    },
                    "syncStartedAt": {
                      "format": "date-time",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "AI sync initiated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Force re-sync of AI Brain without changing profile",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/brain/sync-services": {
      "post": {
        "operationId": "AIBrainController_syncServices",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "added": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "brainUpdatedAt": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "removed": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "synced": {
                      "type": "number"
                    },
                    "updated": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Service offerings synced to AI Brain"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sync service offerings into AI Brain profile",
        "tags": [
          "AI Brain"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/config/kb": {
      "get": {
        "description": "Lists knowledge base articles with pagination, search, and category filtering for assistant ingestion.",
        "operationId": "AiConfigController_findAllKbArticles",
        "parameters": [
          {
            "description": "Filter by article category or tag.",
            "in": "query",
            "name": "category",
            "required": false,
            "schema": {}
          },
          {
            "description": "Free-text query to match titles and content.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          },
          {
            "description": "Maximum articles per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Page number (1-based). Defaults to 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "KB articles retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all knowledge base articles",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Adds a new knowledge base article that becomes available for retrieval augmented generation (RAG) and agent lookups.",
        "operationId": "AiConfigController_createKbArticle",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateKbArticleDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "KB article created successfully"
          },
          "400": {
            "description": "Invalid knowledge base payload"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a knowledge base article",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/config/kb/search/{query}": {
      "get": {
        "description": "Performs semantic and keyword search across knowledge base articles to power ask-the-docs use cases.",
        "operationId": "AiConfigController_searchKb",
        "parameters": [
          {
            "description": "Search string to evaluate",
            "in": "path",
            "name": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Search knowledge base",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/ai/config/kb/{id}": {
      "delete": {
        "description": "Deactivates a knowledge base article and removes it from AI retrieval results.",
        "operationId": "AiConfigController_removeKbArticle",
        "parameters": [
          {
            "description": "Knowledge base article identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "KB article deactivated successfully"
          },
          "404": {
            "description": "KB article not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a knowledge base article",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "description": "Retrieves the full article content, metadata, and embedding status.",
        "operationId": "AiConfigController_findOneKbArticle",
        "parameters": [
          {
            "description": "Knowledge base article identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "KB article retrieved successfully"
          },
          "404": {
            "description": "KB article not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a knowledge base article by ID",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Updates article content, metadata, or publishing state. Re-triggers embedding when content changes.",
        "operationId": "AiConfigController_updateKbArticle",
        "parameters": [
          {
            "description": "Knowledge base article identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateKbArticleDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "KB article updated successfully"
          },
          "400": {
            "description": "Invalid update payload"
          },
          "404": {
            "description": "KB article not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a knowledge base article",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/config": {
      "get": {
        "description": "Fetch public configuration for an embeddable chat widget.",
        "operationId": "WidgetPublicController_getConfig",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/session": {
      "post": {
        "description": "Create a widget chat session.",
        "operationId": "WidgetPublicController_createSession",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWidgetSessionDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/session/{sessionId}": {
      "get": {
        "description": "Read a widget chat session.",
        "operationId": "WidgetPublicController_getSession",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/session/{sessionId}/attachments": {
      "post": {
        "description": "Upload an attachment for a widget chat session.",
        "operationId": "WidgetPublicController_uploadAttachment",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadWidgetAttachmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/session/{sessionId}/messages": {
      "post": {
        "description": "Send a message into a widget chat session.",
        "operationId": "WidgetPublicController_sendMessage",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendWidgetMessageDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/session/{sessionId}/presence/read": {
      "post": {
        "description": "Mark widget session messages as read.",
        "operationId": "WidgetPublicController_updateRead",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWidgetReadDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/api/widget/{widgetKey}/session/{sessionId}/presence/typing": {
      "post": {
        "description": "Send widget typing presence.",
        "operationId": "WidgetPublicController_updateTyping",
        "parameters": [
          {
            "in": "path",
            "name": "widgetKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "origin",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWidgetTypingDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": [
          "Widget"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments": {
      "get": {
        "operationId": "AppointmentsController_findAll__appointments",
        "parameters": [
          {
            "description": "Page number for pagination",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "description": "Number of items per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "example": 10,
              "type": "number"
            }
          },
          {
            "description": "Search term to filter appointments",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "example": "john doe",
              "type": "string"
            }
          },
          {
            "description": "Filter by appointment status",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "scheduled",
                "confirmed",
                "completed",
                "cancelled",
                "no_show"
              ],
              "example": "scheduled",
              "type": "string"
            }
          },
          {
            "description": "Filter by staff member ID",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "example": "staff_123",
              "type": "string"
            }
          },
          {
            "description": "Filter by contact ID",
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "example": "contact_123",
              "type": "string"
            }
          },
          {
            "description": "Filter by location ID",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Filter appointments starting on or after this date (YYYY-MM-DD format)",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-11-11",
              "type": "string"
            }
          },
          {
            "description": "Filter appointments starting on or before this date (YYYY-MM-DD format)",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-11-18",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Appointments retrieved successfully"
          },
          "400": {
            "description": "Invalid date format or query parameters"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all appointments",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "AppointmentsController_create__appointments",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAppointmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Appointment created successfully"
          },
          "400": {
            "description": "Scheduling conflict detected"
          },
          "404": {
            "description": "Service offering or staff not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new appointment",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/analytics/by-service": {
      "get": {
        "operationId": "AppointmentsAnalyticsController_getByService",
        "parameters": [
          {
            "description": "ISO8601 start date for analytics window (defaults to last 30 days).",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-12-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "description": "ISO8601 end date for analytics window (defaults to now).",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-12-25T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "description": "Optional location filter (and timezone source for peak-hours).",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Optional staff filter.",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "example": "staff_123",
              "type": "string"
            }
          },
          {
            "description": "Optional status filter (defaults vary by endpoint).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "example": "completed",
              "type": "string"
            }
          },
          {
            "description": "Number of rows to return.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "maximum": 50,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "description": "Sort key for ranked analytics.",
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "default": "bookings",
              "enum": [
                "bookings",
                "completed",
                "revenue"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Service analytics retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Top services by bookings / completed / revenue",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/analytics/by-staff": {
      "get": {
        "operationId": "AppointmentsAnalyticsController_getByStaff",
        "parameters": [
          {
            "description": "ISO8601 start date for analytics window (defaults to last 30 days).",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-12-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "description": "ISO8601 end date for analytics window (defaults to now).",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-12-25T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "description": "Optional location filter (and timezone source for peak-hours).",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Optional staff filter.",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "example": "staff_123",
              "type": "string"
            }
          },
          {
            "description": "Optional status filter (defaults vary by endpoint).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "example": "completed",
              "type": "string"
            }
          },
          {
            "description": "Number of rows to return.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "maximum": 50,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "description": "Sort key for ranked analytics.",
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "default": "bookings",
              "enum": [
                "bookings",
                "completed",
                "revenue"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Staff analytics retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Top staff by bookings / completed / revenue",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/analytics/export": {
      "get": {
        "operationId": "AppointmentsAnalyticsController_exportCsv",
        "parameters": [
          {
            "description": "ISO8601 start date for analytics window (defaults to last 30 days).",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-12-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "description": "ISO8601 end date for analytics window (defaults to now).",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-12-25T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "description": "Optional location filter (and timezone source for peak-hours).",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Optional staff filter.",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "example": "staff_123",
              "type": "string"
            }
          },
          {
            "description": "Optional status filter (defaults vary by endpoint).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "example": "completed",
              "type": "string"
            }
          },
          {
            "description": "Number of rows to return.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "maximum": 50,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "description": "Sort key for ranked analytics.",
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "default": "bookings",
              "enum": [
                "bookings",
                "completed",
                "revenue"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CSV file stream"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Export appointment analytics as CSV",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/analytics/peak-hours": {
      "get": {
        "operationId": "AppointmentsAnalyticsController_getPeakHours",
        "parameters": [
          {
            "description": "ISO8601 start date for analytics window (defaults to last 30 days).",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-12-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "description": "ISO8601 end date for analytics window (defaults to now).",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-12-25T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "description": "Optional location filter (and timezone source for peak-hours).",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Optional staff filter.",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "example": "staff_123",
              "type": "string"
            }
          },
          {
            "description": "Optional status filter (defaults vary by endpoint).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "example": "completed",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Peak hours analytics retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Peak booking hours (hour-of-day histogram)",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/analytics/summary": {
      "get": {
        "operationId": "AppointmentsAnalyticsController_getSummary",
        "parameters": [
          {
            "description": "ISO8601 start date for analytics window (defaults to last 30 days).",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-12-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "description": "ISO8601 end date for analytics window (defaults to now).",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-12-25T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "description": "Optional location filter (and timezone source for peak-hours).",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Optional staff filter.",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "example": "staff_123",
              "type": "string"
            }
          },
          {
            "description": "Optional status filter (defaults vary by endpoint).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "example": "completed",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Appointment analytics summary retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Appointment analytics summary",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/best-staff": {
      "post": {
        "operationId": "AppointmentsController_findBestStaff__appointments_best_staff",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Best staff assignments found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Find best staff assignment",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/calendar-overview": {
      "get": {
        "operationId": "AppointmentsController_getCalendarOverview__appointments_calendar_overview",
        "parameters": [
          {
            "description": "Start date (YYYY-MM-DD)",
            "in": "query",
            "name": "start",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD)",
            "in": "query",
            "name": "end",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendar overview retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get calendar overview for date range",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/calendar/staff/{staffId}": {
      "get": {
        "operationId": "AppointmentsController_getStaffCalendar__appointments_calendar_staff_staffId",
        "parameters": [
          {
            "in": "path",
            "name": "staffId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start date (ISO 8601)",
            "in": "query",
            "name": "startDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (ISO 8601)",
            "in": "query",
            "name": "endDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Staff calendar retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get appointments for specific staff member in date range",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/conflicts/check": {
      "get": {
        "operationId": "AppointmentsController_checkConflicts__appointments_conflicts_check",
        "parameters": [
          {
            "in": "query",
            "name": "startTime",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endTime",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "resourceIds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "includeBuffers",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Conflict check completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check for scheduling conflicts",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/overview": {
      "get": {
        "operationId": "AppointmentsController_getCalendarOverview__appointments_overview",
        "parameters": [
          {
            "description": "Start date (YYYY-MM-DD)",
            "in": "query",
            "name": "start",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "End date (YYYY-MM-DD)",
            "in": "query",
            "name": "end",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendar overview retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get calendar overview for date range",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/slots/available": {
      "get": {
        "operationId": "AppointmentsController_findAvailableSlots__appointments_slots_available",
        "parameters": [
          {
            "in": "query",
            "name": "serviceOfferingId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "staffId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "bufferBeforeMinutes",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "bufferAfterMinutes",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Available slots retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Find available time slots",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}": {
      "delete": {
        "operationId": "AppointmentsController_remove__appointments_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Appointment cancelled successfully"
          },
          "404": {
            "description": "Appointment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel an appointment",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "AppointmentsController_findOne__appointments_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Appointment retrieved successfully"
          },
          "404": {
            "description": "Appointment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an appointment by ID",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "AppointmentsController_update__appointments_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAppointmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Appointment updated successfully"
          },
          "400": {
            "description": "Scheduling conflict detected"
          },
          "404": {
            "description": "Appointment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update an appointment",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}/cancel": {
      "post": {
        "operationId": "AppointmentsController_cancel__appointments_id_cancel",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Appointment cancelled successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel an appointment (alias)",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}/ics": {
      "get": {
        "operationId": "AppointmentsController_downloadIcs__appointments_id_ics",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ICS generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Download ICS file for appointment",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}/instance": {
      "delete": {
        "operationId": "AppointmentsController_removeInstance__appointments_id_instance",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a single recurring appointment instance",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "AppointmentsController_updateInstance__appointments_id_instance",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAppointmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a single recurring appointment instance",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}/reschedule": {
      "post": {
        "operationId": "AppointmentsController_reschedule__appointments_id_reschedule",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAppointmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Appointment rescheduled successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reschedule an appointment",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}/series": {
      "get": {
        "operationId": "AppointmentsController_getSeries__appointments_id_series",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get recurring appointment series",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/appointments/{id}/transfer": {
      "post": {
        "operationId": "AppointmentsController_transfer__appointments_id_transfer",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferAppointmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Appointment transferred successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Transfer an appointment to another location",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/auth/api-keys": {
      "get": {
        "description": "List or create scoped ServiceAgent API keys.",
        "operationId": "AuthController_listApiKeys",
        "parameters": [],
        "responses": {
          "200": {
            "description": "API keys retrieved"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List API keys",
        "tags": [
          "Auth"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "List or create scoped ServiceAgent API keys.",
        "operationId": "AuthController_createApiKey",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "API key created"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create API key",
        "tags": [
          "Auth"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/auth/api-keys/{id}": {
      "delete": {
        "description": "Revoke a scoped ServiceAgent API key.",
        "operationId": "AuthController_revokeApiKey",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "API key revoked"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Revoke API key",
        "tags": [
          "Auth"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/auth/api-keys/{id}/rotate": {
      "post": {
        "description": "Rotate a scoped ServiceAgent API key.",
        "operationId": "AuthController_rotateApiKey",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "API key rotated; plaintext secret returned once"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Rotate API key secret",
        "tags": [
          "Auth"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls": {
      "get": {
        "description": "Returns paginated call records with optional status and direction filters.",
        "operationId": "CallsController_findAll",
        "parameters": [
          {
            "description": "Filter by call direction (inbound/outbound).",
            "in": "query",
            "name": "direction",
            "required": false,
            "schema": {}
          },
          {
            "description": "Filter by call status.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "description": "Maximum calls per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Page number (1-based).",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calls retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all calls",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/batch-analyze-sentiment": {
      "post": {
        "description": "Triggers sentiment analysis for multiple calls.",
        "operationId": "CallsController_batchAnalyzeSentiment",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchAnalyzeCallSentimentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Batch analysis queued"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Batch analyze sentiment",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/outbound": {
      "post": {
        "description": "Starts an outbound call from an AI agent to a destination number.",
        "operationId": "CallsController_initiateOutbound",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InitiateOutboundCallDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Call initiated successfully."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Initiate an outbound call",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/unified": {
      "get": {
        "operationId": "UnifiedCallsController_listCalls",
        "parameters": [
          {
            "in": "query",
            "name": "sortOrder",
            "required": false,
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "enum": [
                "startedAt",
                "duration",
                "sentiment"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "agentId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "handler",
            "required": false,
            "schema": {
              "enum": [
                "ai",
                "human"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "direction",
            "required": false,
            "schema": {
              "enum": [
                "inbound",
                "outbound"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "enum": [
                "all",
                "aiva",
                "dialer"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List unified calls across voice providers, AIVA, and Dialer",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/unified/active": {
      "get": {
        "operationId": "UnifiedCallsController_getActiveCalls",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List active unified calls for realtime dashboard",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/unified/analytics": {
      "get": {
        "operationId": "UnifiedCallsController_getAnalytics",
        "parameters": [
          {
            "in": "query",
            "name": "groupBy",
            "required": false,
            "schema": {
              "enum": [
                "hour",
                "day",
                "week",
                "month"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "enum": [
                "all",
                "aiva",
                "dialer"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "timeRange",
            "required": false,
            "schema": {
              "enum": [
                "24h",
                "7d",
                "30d",
                "90d",
                "custom"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get unified call analytics across all sources",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/unified/analytics/export": {
      "get": {
        "operationId": "UnifiedCallsController_exportAnalyticsCsv",
        "parameters": [
          {
            "in": "query",
            "name": "groupBy",
            "required": false,
            "schema": {
              "enum": [
                "hour",
                "day",
                "week",
                "month"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "enum": [
                "all",
                "aiva",
                "dialer"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "timeRange",
            "required": false,
            "schema": {
              "enum": [
                "24h",
                "7d",
                "30d",
                "90d",
                "custom"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Export unified call analytics as CSV",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/unified/{callId}": {
      "get": {
        "operationId": "UnifiedCallsController_getCallDetail",
        "parameters": [
          {
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get unified call detail by call ID",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/calls/{callId}/analyze-sentiment": {
      "post": {
        "description": "Triggers sentiment analysis for a specific call.",
        "operationId": "CallsController_analyzeSentiment",
        "parameters": [
          {
            "description": "Call identifier",
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyzeCallSentimentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Sentiment analysis queued successfully"
          },
          "404": {
            "description": "Call not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Analyze call sentiment",
        "tags": [
          "Calls"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/companies": {
      "get": {
        "description": "Returns a paginated list of companies for the organization. Supports text search and page-based pagination.",
        "operationId": "CompaniesController_findAll",
        "parameters": [
          {
            "description": "Case-insensitive search across company name and domain.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          },
          {
            "description": "Maximum companies per page. Defaults to service-level pagination size.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Page number (1-based). Defaults to 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Companies retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all companies",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Creates a company profile for the organization including key attributes such as industry, size, and primary contacts.",
        "operationId": "CompaniesController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCompanyDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Company created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new company",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/companies/bulk-update": {
      "post": {
        "operationId": "CompaniesController_bulkUpdate",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkUpdateCompaniesDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Bulk update completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Bulk update companies",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/companies/merge": {
      "post": {
        "description": "Consolidates a secondary company into a primary company, moving linked contacts and deals. Only privileged roles may perform this action.",
        "operationId": "CompaniesController_merge",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergeCompaniesDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Companies merged successfully"
          },
          "403": {
            "description": "Forbidden - insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Merge companies",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/companies/{id}": {
      "delete": {
        "description": "Permanently removes a company and its associations. Restricted to owner/admin roles due to data loss risk.",
        "operationId": "CompaniesController_remove",
        "parameters": [
          {
            "description": "Company identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Company deleted successfully"
          },
          "403": {
            "description": "Forbidden - insufficient permissions"
          },
          "404": {
            "description": "Company not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a company",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "description": "Retrieves a company record along with related contacts and metadata. Returns 404 if the company is not part of the organization.",
        "operationId": "CompaniesController_findOne",
        "parameters": [
          {
            "description": "Company identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Company retrieved successfully"
          },
          "404": {
            "description": "Company not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a company by ID",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Partially updates company details such as address, ownership, or associated tags.",
        "operationId": "CompaniesController_update",
        "parameters": [
          {
            "description": "Company identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCompanyDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Company updated successfully"
          },
          "404": {
            "description": "Company not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a company",
        "tags": [
          "CRM Companies"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts": {
      "get": {
        "description": "Retrieves paginated contacts for the organization with optional filtering by lifecycle status and text search.",
        "operationId": "ContactsController_findAll",
        "parameters": [
          {
            "description": "Comma-separated tags to match.",
            "in": "query",
            "name": "tags",
            "required": false,
            "schema": {}
          },
          {
            "description": "JSON encoded advanced filter definition.",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {}
          },
          {
            "description": "Apply saved filter by identifier.",
            "in": "query",
            "name": "filterId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Comma-separated lifecycle stage identifiers.",
            "in": "query",
            "name": "lifecycleStageIds",
            "required": false,
            "schema": {}
          },
          {
            "description": "Filter by owner identifier.",
            "in": "query",
            "name": "ownerId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Filter by contact status (e.g., ACTIVE, INACTIVE).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "description": "Case-insensitive search across name, email, and company fields.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          },
          {
            "description": "Set true to force cursor response shape even for the first page (cursorId omitted).",
            "in": "query",
            "name": "cursorMode",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Optional cursor-based pagination. When provided (or when cursorMode=true), returns { items, nextCursorId } instead of an array.",
            "in": "query",
            "name": "cursorId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Maximum contacts per page. Defaults to service pagination size.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Page number (1-based). Defaults to 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contacts retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all contacts",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Creates a contact profile for the organization, including demographic details, owner assignment, and linked companies.",
        "operationId": "ContactsController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Contact created successfully"
          },
          "409": {
            "description": "Contact already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new contact",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/bulk-update": {
      "post": {
        "operationId": "ContactsController_bulkUpdate",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkUpdateContactsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Bulk update completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Bulk update contacts",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/dedupe": {
      "post": {
        "description": "Merges duplicate contacts into a single primary record. Restricted to owner/admin due to destructive changes.",
        "operationId": "ContactsController_dedupe",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DedupeContactsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Contacts deduplicated successfully"
          },
          "403": {
            "description": "Forbidden - insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Deduplicate contacts",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/enrichment/batch": {
      "post": {
        "description": "Returns enrichment payloads for up to 50 contacts. Missing contacts are returned in a separate list.",
        "operationId": "ContactsController_batchContactEnrichment",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchContactEnrichmentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Batch contact enrichment retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Batch contact enrichment",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/export": {
      "post": {
        "operationId": "ContactsController_exportContacts",
        "parameters": [
          {
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "pdf"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Export generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Export contacts (csv/pdf)",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/export-csv": {
      "get": {
        "description": "Generates a CSV export of all contacts for the current organization.",
        "operationId": "ContactsController_exportContactsCsv",
        "parameters": [],
        "responses": {
          "200": {
            "description": "CSV export generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Export contacts to CSV",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/filters": {
      "get": {
        "operationId": "SavedFiltersController_list",
        "parameters": [
          {
            "description": "Filter entity type",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "default": "contacts",
              "enum": [
                "contacts",
                "companies",
                "deals"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "minimum": 1,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List saved filters",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "SavedFiltersController_create",
        "parameters": [
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedFilterDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Filter created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create saved filter",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/filters/{id}": {
      "delete": {
        "operationId": "SavedFiltersController_remove",
        "parameters": [
          {
            "description": "Saved filter identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Filter deleted successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete saved filter",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "SavedFiltersController_updatePatchAlias",
        "parameters": [
          {
            "description": "Saved filter identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSavedFilterDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update saved filter (alias)",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "SavedFiltersController_update",
        "parameters": [
          {
            "description": "Saved filter identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSavedFilterDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update saved filter",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/filters/{id}/run": {
      "post": {
        "operationId": "SavedFiltersController_run",
        "parameters": [
          {
            "description": "Saved filter identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 200,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": "createdAt",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "order",
            "required": false,
            "schema": {
              "default": "desc",
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute saved filter and return matching records",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/analyze": {
      "post": {
        "description": "Uploads a CSV file, analyzes headers and sample data, and returns suggested field mappings.",
        "operationId": "ContactsController_analyzeImportCsv",
        "parameters": [],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "file": {
                    "description": "CSV file containing contacts to import",
                    "format": "binary",
                    "type": "string"
                  }
                },
                "required": [
                  "file"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "CSV analyzed successfully"
          },
          "400": {
            "description": "Invalid CSV file"
          },
          "413": {
            "description": "File too large"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Analyze CSV import file",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/execute": {
      "post": {
        "description": "Processes a previously analyzed CSV file, validates all rows, and imports valid contacts in bulk.",
        "operationId": "ContactsController_executeImportCsv",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecuteContactsImportDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "CSV import executed successfully"
          },
          "400": {
            "description": "Invalid mapping or malformed CSV"
          },
          "404": {
            "description": "Filestack handle not found"
          },
          "422": {
            "description": "No valid data to import"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute CSV contact import",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/execute-hybrid": {
      "post": {
        "description": "Hybrid mode: auto-merge high-confidence duplicates (exact email/phone match + consistent name), create new contacts for unmatched rows, and queue the rest for review.",
        "operationId": "ContactsController_executeHybridImportCsv",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecuteHybridContactsImportDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Hybrid CSV import executed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute hybrid CSV contact import",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/preview": {
      "post": {
        "description": "Classifies CSV rows into: new contacts, auto-merge candidates (high confidence), review-needed matches (name mismatch / ambiguous), and invalid rows.",
        "operationId": "ContactsController_previewImportCsv",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewContactsImportDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "CSV import preview generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preview hybrid CSV contact import",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/review-tasks": {
      "get": {
        "operationId": "ContactsController_listImportReviewTasks",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List open CSV import review tasks",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/review-tasks/{taskId}": {
      "get": {
        "operationId": "ContactsController_getImportReviewTask",
        "parameters": [
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a CSV import review task with candidates",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/import-csv/review-tasks/{taskId}/resolve": {
      "post": {
        "operationId": "ContactsController_resolveImportReviewTask",
        "parameters": [
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveImportReviewTaskDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resolve a CSV import review task (merge/create/ignore)",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/lifecycle-stages": {
      "get": {
        "operationId": "LifecycleStagesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List lifecycle stages for the organization",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/lifecycle-stages/apply-preset": {
      "post": {
        "operationId": "LifecycleStagesController_applyPreset",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyLifecyclePresetDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Apply a lifecycle preset to rename and reorder stages",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/lifecycle-stages/presets/list": {
      "get": {
        "operationId": "LifecycleStagesController_presets",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available lifecycle stage presets",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/lifecycle-stages/{id}": {
      "patch": {
        "operationId": "LifecycleStagesController_update",
        "parameters": [
          {
            "description": "Lifecycle stage identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLifecycleStageDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update lifecycle stage properties (rename, probability, routing)",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}": {
      "delete": {
        "description": "Permanently deletes a contact and associated analytics. Ensure no critical workflows depend on this record before deletion.",
        "operationId": "ContactsController_remove",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact deleted successfully"
          },
          "404": {
            "description": "Contact not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a contact",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Partially updates contact attributes including profile fields, ownership, lifecycle stage, or custom fields.",
        "operationId": "ContactsController_update",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Contact updated successfully"
          },
          "404": {
            "description": "Contact not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a contact",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/behavioral-profile": {
      "patch": {
        "description": "Manually updates the behavioral profile for a contact, overriding AI-detected behaviors when necessary.",
        "operationId": "ContactsController_updateBehavioralProfile",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Behavioral profile updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update behavioral profile",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/contextual-profile": {
      "patch": {
        "description": "Updates contextual understanding (e.g., buyer journey stage, preferences) for a contact.",
        "operationId": "ContactsController_updateContextualProfile",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contextual profile updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update contextual profile",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/enrichment": {
      "get": {
        "description": "Returns aggregated enrichment signals (calls, tickets, surveys, invoices) plus a computed health score and risk flags.",
        "operationId": "ContactsController_getContactEnrichment",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "If true, bypass cache and recompute enrichment.",
            "in": "query",
            "name": "refresh",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact enrichment retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact enrichment",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/insights": {
      "get": {
        "description": "Returns AI-generated insights highlighting recommended actions, risks, and opportunities for the contact.",
        "operationId": "ContactsController_getContactInsights",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact insights retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact insights",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/insights/{insightId}": {
      "delete": {
        "description": "Dismisses an insight so it no longer appears in the contact dashboard.",
        "operationId": "ContactsController_dismissInsight",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Insight identifier",
            "in": "path",
            "name": "insightId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Insight dismissed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dismiss an insight",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/insights/{insightId}/action": {
      "post": {
        "description": "Marks a specific insight as acted upon and records optional notes about the action.",
        "operationId": "ContactsController_markInsightAction",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Insight identifier",
            "in": "path",
            "name": "insightId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightActionDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Insight action marked successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark insight action as taken",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/intelligence": {
      "get": {
        "description": "Retrieves aggregated intelligence for the contact including AI-enriched insights and recommended actions.",
        "operationId": "ContactsController_getContactIntelligence",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact intelligence retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact intelligence data",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/intelligence/refresh": {
      "post": {
        "description": "Recomputes contact intelligence insights, triggering downstream AI pipelines to refresh scores and recommendations.",
        "operationId": "ContactsController_refreshContactIntelligence",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact intelligence refreshed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Refresh contact intelligence",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/network": {
      "get": {
        "description": "Returns the extended network graph for the contact to help visualize multi-hop relationships.",
        "operationId": "ContactsController_getContactNetwork",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Depth of the network traversal (default defined by service).",
            "in": "query",
            "name": "depth",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact network retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact network",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/predictions": {
      "get": {
        "description": "Retrieves predictive metrics such as deal conversion likelihood and churn risk for the contact.",
        "operationId": "ContactsController_getContactPredictions",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PredictiveAnalyticsDto"
                }
              }
            },
            "description": "Predictive analytics retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get predictive analytics",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/predictive-profile": {
      "patch": {
        "description": "Overrides predictive scoring outputs for the contact with manually curated values.",
        "operationId": "ContactsController_updatePredictiveProfile",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Predictive profile updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update predictive profile",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/relationship-profile": {
      "patch": {
        "description": "Updates relationship strength and connection mapping details for the contact.",
        "operationId": "ContactsController_updateRelationshipProfile",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Relationship profile updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update relationship profile",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/relationships": {
      "get": {
        "description": "Returns relationship graph information such as reporting structure or partner connections.",
        "operationId": "ContactsController_getContactRelationships",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact relationships retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact relationships",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/scores": {
      "get": {
        "description": "Returns behavioral scoring metrics (engagement, intent, health) for the contact.",
        "operationId": "ContactsController_getContactScores",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Behavioral scores retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get behavioral scores",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/scores/calculate": {
      "post": {
        "description": "Forces recalculation of behavioral scoring pipelines for the contact. Useful after large data imports or corrections.",
        "operationId": "ContactsController_calculateBehavioralScores",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Behavioral scores recalculated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Recalculate behavioral scores",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/contacts/{id}/timeline": {
      "get": {
        "description": "Returns chronological timeline events (emails, calls, activities) for the contact. Supports limiting event count.",
        "operationId": "ContactsController_getContactTimeline",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum timeline events to return.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact timeline retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get contact timeline",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Adds a custom timeline event (note, meeting, call, etc.) to the contact history.",
        "operationId": "ContactsController_addTimelineEvent",
        "parameters": [
          {
            "description": "Contact identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTimelineEventDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Timeline event created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add timeline event",
        "tags": [
          "CRM Contacts"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/deals": {
      "get": {
        "description": "Retrieves paginated deals for the current organization. Supports filtering by ownership, pipeline, stage, company, contact, status, and text search.",
        "operationId": "DealsController_findAll",
        "parameters": [
          {
            "description": "Filter by related contact.",
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Filter by related company.",
            "in": "query",
            "name": "companyId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Restrict results to a stage within the selected pipeline.",
            "in": "query",
            "name": "stageId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Restrict results to a pipeline.",
            "in": "query",
            "name": "pipelineId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Filter deals owned by the specified teammate.",
            "in": "query",
            "name": "ownerId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Filter by lifecycle status (e.g., OPEN, WON, LOST).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "description": "Free-text search across deal titles and related entities.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          },
          {
            "description": "Set true to force cursor response shape even for the first page (cursorId omitted).",
            "in": "query",
            "name": "cursorMode",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Optional cursor-based pagination. When provided (or when cursorMode=true), returns { items, nextCursorId } instead of an array.",
            "in": "query",
            "name": "cursorId",
            "required": false,
            "schema": {}
          },
          {
            "description": "Max items per page. Defaults to service-level default.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Page number (1-based). Defaults to 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deals retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all deals",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Creates a deal associated with the current organization. Deals can optionally reference contacts, companies, and pipelines.",
        "operationId": "DealsController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDealDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Deal created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new deal",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/deals/analytics": {
      "get": {
        "operationId": "DealsController_getAnalytics",
        "parameters": [
          {
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "enum": [
                "week",
                "month",
                "year"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deal analytics retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get deal analytics for a period",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/deals/bulk-update": {
      "post": {
        "operationId": "DealsController_bulkUpdate",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkUpdateDealsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Bulk update completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Bulk update deals",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/deals/{id}": {
      "delete": {
        "description": "Deletes a deal permanently. Consider archiving via status update instead if history must be preserved.",
        "operationId": "DealsController_remove",
        "parameters": [
          {
            "description": "Deal identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deal deleted successfully"
          },
          "404": {
            "description": "Deal not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a deal",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "description": "Returns a single deal with its relationships and stage data. The deal must belong to the current organization.",
        "operationId": "DealsController_findOne",
        "parameters": [
          {
            "description": "Deal identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deal retrieved successfully"
          },
          "404": {
            "description": "Deal not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a deal by ID",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Updates deal fields such as title, value, owner, pipeline, or stage. Partial updates are supported.",
        "operationId": "DealsController_update",
        "parameters": [
          {
            "description": "Deal identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDealDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Deal updated successfully"
          },
          "404": {
            "description": "Deal not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a deal",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "description": "Updates deal fields such as title, value, owner, pipeline, or stage. Supports partial updates.",
        "operationId": "DealsController_updatePut",
        "parameters": [
          {
            "description": "Deal identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDealDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Deal updated successfully"
          },
          "404": {
            "description": "Deal not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a deal (PUT)",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/deals/{id}/transfer": {
      "post": {
        "operationId": "DealsController_transfer",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferDealDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Deal transferred successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Transfer a deal to another location",
        "tags": [
          "CRM Deals"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails": {
      "get": {
        "operationId": "EmailsController_getEmailThread__emails",
        "parameters": [
          {
            "in": "query",
            "name": "contactId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "contact_id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "company_id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "deal_id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Email thread retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get email thread/history",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/analytics/overview": {
      "get": {
        "operationId": "EmailsController_getEmailAnalytics__emails_analytics_overview",
        "parameters": [
          {
            "in": "query",
            "name": "date_range",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Email analytics retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get email analytics overview",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/attachments": {
      "post": {
        "operationId": "EmailsController_uploadAttachmentAlias__emails_attachments",
        "parameters": [],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "file": {
                    "format": "binary",
                    "type": "string"
                  }
                },
                "required": [
                  "file"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Attachment uploaded successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload an email attachment (spec alias)",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/bulk-send": {
      "post": {
        "operationId": "EmailsController_sendBulkEmails__emails_bulk_send",
        "parameters": [
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendBulkEmailDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Bulk emails queued successfully"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send bulk emails",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/send": {
      "post": {
        "operationId": "EmailsController_sendEmail__emails_send",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Email sent successfully"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send individual email",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/templates": {
      "get": {
        "operationId": "EmailsController_getTemplates__emails_templates",
        "parameters": [
          {
            "in": "query",
            "name": "category",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all email templates",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "EmailsController_createTemplate__emails_templates",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmailTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Template created successfully"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create email template",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/templates/industry/{industry}": {
      "get": {
        "operationId": "EmailsController_getIndustryTemplates__emails_templates_industry_industry",
        "parameters": [
          {
            "in": "path",
            "name": "industry",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Industry templates retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get industry-specific template suggestions",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/templates/{id}": {
      "delete": {
        "operationId": "EmailsController_deleteTemplate__emails_templates_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template deleted successfully"
          },
          "400": {
            "description": "Cannot delete template in use"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete email template",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "EmailsController_getTemplate__emails_templates_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get single email template",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "EmailsController_updateTemplate__emails_templates_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEmailTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Template updated successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update email template",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/templates/{id}/analytics": {
      "get": {
        "operationId": "EmailsController_getTemplateAnalytics__emails_templates_id_analytics",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template analytics retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get template analytics",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/upload-attachment": {
      "post": {
        "operationId": "EmailsController_uploadAttachment__emails_upload_attachment",
        "parameters": [],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "file": {
                    "description": "Attachment file (max 1MB on free plan, 10MB on paid plan)",
                    "format": "binary",
                    "type": "string"
                  }
                },
                "required": [
                  "file"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Attachment uploaded successfully"
          },
          "400": {
            "description": "Invalid attachment"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload an email attachment",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/emails/{id}": {
      "get": {
        "operationId": "EmailsController_getEmail__emails_id",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Email details retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Email not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get single email details",
        "tags": [
          "Email"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/inbox/messages": {
      "get": {
        "operationId": "InboxController_getMessages",
        "parameters": [
          {
            "description": "Limit",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "description": "Thread ID",
            "in": "query",
            "name": "threadId",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Messages retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get messages",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "InboxController_sendMessage",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Message sent successfully"
          },
          "400": {
            "description": "Bad request"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send a message",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/inbox/telegram/connect-link": {
      "post": {
        "operationId": "InboxController_createTelegramConnectLink",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Telegram connect link created"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Telegram connect link for current user",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/inbox/telegram/connections": {
      "get": {
        "operationId": "InboxController_getTelegramConnections",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Telegram connections retrieved"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List Telegram chats connected by current user",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/inbox/telegram/connections/{chatId}": {
      "delete": {
        "operationId": "InboxController_deleteTelegramConnection",
        "parameters": [
          {
            "in": "path",
            "name": "chatId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Telegram connection removed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disconnect a Telegram chat from current user",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/inbox/threads": {
      "get": {
        "operationId": "InboxController_getThreads",
        "parameters": [
          {
            "in": "query",
            "name": "unreadOnly",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Thread status",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "description": "Thread type",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {}
          },
          {
            "description": "Search term",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          },
          {
            "description": "Items per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "description": "Page number",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Message threads retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all message threads",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "InboxController_createThread",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Message thread created successfully"
          },
          "400": {
            "description": "Bad request"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new message thread",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/inbox/threads/{id}": {
      "get": {
        "operationId": "InboxController_getThread",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Message thread retrieved successfully"
          },
          "404": {
            "description": "Message thread not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a message thread by ID",
        "tags": [
          "Inbox"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/install/exchange": {
      "post": {
        "description": "Exchanges an install token for a long-lived API key. Only works for claimed workspaces.",
        "operationId": "InstallController_exchange",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InstallExchangeDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "API key returned"
          }
        },
        "summary": "Exchange install token for API key (server-only)",
        "tags": [
          "Install"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/install/magic-link/send": {
      "post": {
        "description": "Sends a magic link email to claim the demo workspace without password.",
        "operationId": "InstallController_sendMagicLink",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendMagicLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Magic link sent"
          }
        },
        "summary": "Send magic link to claim workspace (passwordless)",
        "tags": [
          "Install"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/install/magic-link/verify": {
      "post": {
        "description": "Verifies the magic link token and claims the workspace.",
        "operationId": "InstallController_verifyMagicLink",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyMagicLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Claim completed"
          }
        },
        "summary": "Verify magic link and complete claim",
        "tags": [
          "Install"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/install/start": {
      "post": {
        "description": "Creates a demo workspace with a chat widget and returns embed snippets. No account required.",
        "operationId": "InstallController_start",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InstallStartDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Install started"
          }
        },
        "summary": "Start instant install: create demo workspace + chat widget",
        "tags": [
          "Install"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/install/status": {
      "get": {
        "description": "Polls the install session to see whether the demo workspace has been claimed yet. Used by CLIs / MCP servers to drive an in-IDE claim flow without consuming the install token via /install/exchange.",
        "operationId": "InstallController_status",
        "parameters": [
          {
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "`{ claimed, claimedAt, expiresAt, organizationId, widgetKey, isDemo }` — `claimed: true` means /install/exchange is now safe to call."
          }
        },
        "summary": "Check install session status by token",
        "tags": [
          "Install"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations": {
      "get": {
        "operationId": "IntegrationController_getIntegrations",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Integrations retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all integrations for organization",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "IntegrationController_createIntegration",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Integration created successfully"
          },
          "400": {
            "description": "Invalid integration data"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new CRM integration",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/asana/projects": {
      "get": {
        "operationId": "IntegrationController_getAsanaProjects",
        "parameters": [
          {
            "in": "query",
            "name": "workspaceGid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asana projects retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Asana projects",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "IntegrationController_createAsanaProject",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Asana project created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Asana project",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/asana/projects/{projectId}/tasks": {
      "get": {
        "operationId": "IntegrationController_getAsanaProjectTasks",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asana tasks retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Asana project tasks",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/asana/tasks": {
      "post": {
        "operationId": "IntegrationController_createAsanaTask",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Asana task created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Asana task",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/asana/tasks/{taskId}": {
      "patch": {
        "operationId": "IntegrationController_updateAsanaTask",
        "parameters": [
          {
            "in": "path",
            "name": "taskId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asana task updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update Asana task",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/asana/workspaces": {
      "get": {
        "operationId": "IntegrationController_getAsanaWorkspaces",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Asana workspaces retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Asana workspaces",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/available": {
      "get": {
        "operationId": "IntegrationController_getAvailableIntegrations",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Available integrations retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available integrations with metadata",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/available-crms": {
      "get": {
        "operationId": "IntegrationController_getAvailableCRMs",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Available CRMs retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get list of available CRM types",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/calendar/available": {
      "get": {
        "operationId": "IntegrationController_getCalendarIntegrations",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Calendar integrations retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available calendar integrations",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/calendly/event-types": {
      "get": {
        "operationId": "IntegrationController_getCalendlyEventTypes",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Calendly event types retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Calendly event types",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/calendly/scheduled-events": {
      "get": {
        "operationId": "IntegrationController_getCalendlyScheduledEvents",
        "parameters": [
          {
            "in": "query",
            "name": "count",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "minStartTime",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "maxStartTime",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendly scheduled events retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Calendly scheduled events",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/calendly/scheduled-events/{eventId}/invitees": {
      "get": {
        "operationId": "IntegrationController_getCalendlyInvitees",
        "parameters": [
          {
            "in": "path",
            "name": "eventId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendly invitees retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Calendly invitees for an event",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/catalog": {
      "get": {
        "description": "Alias of /integrations/available for the frontend catalog. Includes tier, connectMethod, connectPath, capabilities, and category.",
        "operationId": "IntegrationController_getIntegrationsCatalog",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Integration catalog retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List integration catalog with tier + connection metadata",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/connect": {
      "post": {
        "operationId": "IntegrationController_connectIntegration",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Integration connection initiated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Connect a new integration (OAuth or API-key)",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/health": {
      "get": {
        "operationId": "IntegrationController_getIntegrationHealth",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Health status retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all integrations health status",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/health/summary": {
      "get": {
        "operationId": "IntegrationController_getHealthStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Health status retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get health status of all integrations",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/sync-all": {
      "post": {
        "operationId": "IntegrationController_syncAllIntegrations",
        "parameters": [],
        "responses": {
          "200": {
            "description": "All integrations synced successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sync all active integrations",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/appointments": {
      "get": {
        "operationId": "IntegrationController_getCRMAppointments",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "startBefore",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "startAfter",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Appointments retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get CRM appointments",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "IntegrationController_createCRMAppointment",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Appointment created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create CRM appointment",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/contacts": {
      "get": {
        "operationId": "IntegrationController_getCRMContacts",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "phone",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "email",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Contacts retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get CRM contacts",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "IntegrationController_createCRMContact",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Contact created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create CRM contact",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/contacts/{contactId}": {
      "patch": {
        "operationId": "IntegrationController_updateCRMContact",
        "parameters": [
          {
            "in": "path",
            "name": "contactId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update CRM contact",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/deals": {
      "get": {
        "operationId": "IntegrationController_getCRMDeals",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Deals retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get CRM deals",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "IntegrationController_createCRMDeal",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Deal created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create CRM deal",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/deals/{dealId}": {
      "patch": {
        "operationId": "IntegrationController_updateCRMDeal",
        "parameters": [
          {
            "in": "path",
            "name": "dealId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deal updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update CRM deal",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/field-mappings": {
      "get": {
        "operationId": "IntegrationController_getFieldMappings",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Field mappings retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get field mappings for integration",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "IntegrationController_updateFieldMappings",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Field mappings updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update field mappings for integration",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/metadata": {
      "get": {
        "operationId": "IntegrationController_getCRMMetadata",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Metadata retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get CRM metadata and capabilities",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/oauth/callback": {
      "post": {
        "operationId": "IntegrationController_handleOAuthCallback",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OAuth completed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Handle OAuth callback",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/oauth/initiate": {
      "post": {
        "operationId": "IntegrationController_initiateOAuth",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OAuth URL generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Initiate OAuth flow",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/status": {
      "get": {
        "operationId": "IntegrationController_getIntegrationStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Status retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get integration status and health",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/sync": {
      "post": {
        "operationId": "IntegrationController_syncData",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sync completed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sync data with CRM",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/integrations/{crmType}/validate-credentials": {
      "post": {
        "operationId": "IntegrationController_validateCredentials",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Credentials validated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Validate CRM credentials",
        "tags": [
          "Integrations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-base": {
      "get": {
        "operationId": "KnowledgeBaseAliasController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Knowledge base articles retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias: list knowledge base articles",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "KnowledgeBaseAliasController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateKbArticleDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Knowledge base article created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias: create knowledge base article",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-base/analytics": {
      "get": {
        "operationId": "KnowledgeBaseAliasController_analytics",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Knowledge base analytics + recent queries",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-base/articles": {
      "get": {
        "description": "Returns org KB articles with minimal fields, supports search. This is the canonical list for knowledge_article_ids selection.",
        "operationId": "KnowledgeBaseArticlesController_listArticles",
        "parameters": [
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List org knowledge base articles (for agent picker)",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-base/{id}": {
      "delete": {
        "operationId": "KnowledgeBaseAliasController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Knowledge base article deleted successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias: delete knowledge base article",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "KnowledgeBaseAliasController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateKbArticleDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Knowledge base article updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias: update knowledge base article",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-bases": {
      "get": {
        "operationId": "KnowledgeBasesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List knowledge bases",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "KnowledgeBasesController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateKnowledgeBaseDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create knowledge base",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-bases/{id}": {
      "delete": {
        "operationId": "KnowledgeBasesController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete knowledge base",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "KnowledgeBasesController_get",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get knowledge base details",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-bases/{id}/documents": {
      "post": {
        "operationId": "KnowledgeBasesController_uploadDocument",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadKnowledgeDocumentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload a knowledge base document (url/text/fileUrl)",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-bases/{id}/documents/{docId}": {
      "delete": {
        "operationId": "KnowledgeBasesController_removeDocument",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "docId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a knowledge base document",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/knowledge-bases/{id}/sync": {
      "post": {
        "operationId": "KnowledgeBasesController_sync",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Trigger re-indexing (embedding regeneration) for a knowledge base",
        "tags": [
          "Knowledge"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/locations": {
      "get": {
        "operationId": "LocationsController_findAll",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Locations retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all locations",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "LocationsController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocationDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Location created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new location",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/locations/service-request": {
      "post": {
        "operationId": "LocationsPublicController_createServiceRequest",
        "parameters": [
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateServiceRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Service request received successfully"
          }
        },
        "summary": "Create a public service request for unserved areas",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/locations/{id}": {
      "delete": {
        "operationId": "LocationsController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Location deleted successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a location",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "LocationsController_findOne",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Location retrieved successfully"
          },
          "404": {
            "description": "Location not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a location by ID",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "LocationsController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocationDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Location updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a location",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/locations/{id}/availability": {
      "get": {
        "operationId": "LocationsController_getAvailability",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Availability retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get location availability",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/locations/{id}/default": {
      "post": {
        "operationId": "LocationsController_setDefaultLocation",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Default location updated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set organization default location",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/locations/{id}/staff": {
      "get": {
        "operationId": "LocationsController_getLocationStaff",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List staff assigned to this location",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "LocationsController_setLocationStaff",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetLocationStaffDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace staff assignments for this location",
        "tags": [
          "Locations"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/mcp": {
      "post": {
        "description": "Model Context Protocol endpoint for AI tools.",
        "operationId": "McpGatewayController_handleMcpProtocol",
        "parameters": [
          {
            "description": "Idempotency key for POST/PATCH operations",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Request ID for tracing",
            "in": "header",
            "name": "X-Request-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Tenant ID",
            "in": "header",
            "name": "X-Tenant-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tenant-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-request-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "mcp-session-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "MCP protocol message handled"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Handle MCP protocol messages (JSON-RPC 2.0) via Streamable HTTP transport",
        "tags": [
          "MCP"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/mcp/tools": {
      "post": {
        "description": "Execute a ServiceAgent MCP tool.",
        "operationId": "McpGatewayController_executeTool",
        "parameters": [
          {
            "description": "Idempotency key for POST/PATCH operations",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Request ID for tracing",
            "in": "header",
            "name": "X-Request-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Tenant ID",
            "in": "header",
            "name": "X-Tenant-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tenant-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-request-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/McpToolRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/McpToolResponseDto"
                }
              }
            },
            "description": "Tool executed successfully"
          },
          "400": {
            "description": "Invalid tool request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden - insufficient scope"
          },
          "429": {
            "description": "Rate limited"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Execute MCP tool",
        "tags": [
          "MCP"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/mcp/tools/list": {
      "post": {
        "description": "JSON-RPC compatible MCP tool listing endpoint.",
        "operationId": "McpGatewayController_listTools",
        "parameters": [
          {
            "description": "Idempotency key for POST/PATCH operations",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Request ID for tracing",
            "in": "header",
            "name": "X-Request-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Tenant ID",
            "in": "header",
            "name": "X-Tenant-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tools listed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available MCP tools",
        "tags": [
          "MCP"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/analytics": {
      "get": {
        "operationId": "PaymentsController_getPaymentAnalytics",
        "parameters": [
          {
            "in": "query",
            "name": "startDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Analytics retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get payment analytics",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/analytics/forecast": {
      "get": {
        "operationId": "PaymentsController_getRevenueForecast",
        "parameters": [
          {
            "in": "query",
            "name": "months",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Forecast retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get revenue forecast",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/analytics/trends": {
      "get": {
        "operationId": "PaymentsController_getInvoiceTrends",
        "parameters": [
          {
            "in": "query",
            "name": "period",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trends retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get invoice trends",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/account": {
      "delete": {
        "operationId": "PaymentsController_disconnectConnectAccount",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Connect account disconnected successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disconnect Stripe Connect account",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "PaymentsController_getConnectAccount",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Account retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Stripe Connect account for organization",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "PaymentsController_createConnectAccount",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateConnectAccountDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Connect account created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Stripe Connect account",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/account-link": {
      "post": {
        "operationId": "PaymentsController_createAccountLinkLegacy",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccountLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Account link created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Stripe Connect account link (legacy route)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/account-status": {
      "get": {
        "operationId": "PaymentsController_getConnectAccountStatusAlias",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Stripe Connect account status (wiring guide route)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/account/link": {
      "post": {
        "operationId": "PaymentsController_createAccountLink",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccountLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Account link created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Stripe Connect account link",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/account/status": {
      "get": {
        "operationId": "PaymentsController_getConnectAccountStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Account status retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Stripe Connect account status for current organization",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/balance": {
      "get": {
        "operationId": "PaymentsController_getConnectedBalance",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Balance retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get connected account balance",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/create-account": {
      "post": {
        "operationId": "PaymentsController_createConnectAccountAlias",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateConnectAccountDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Stripe Connect account (wiring guide route)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/create-account-link": {
      "post": {
        "operationId": "PaymentsController_createAccountLinkAlias",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccountLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Stripe Connect account link (wiring guide route)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/create-payment-link": {
      "post": {
        "operationId": "PaymentsController_createConnectPaymentLinkAlias",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a payment link for a customer (wiring guide route)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/payment-links": {
      "post": {
        "operationId": "PaymentsController_createConnectPaymentLink",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Payment link created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create payment link routed through connected account",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/connect/payouts": {
      "get": {
        "operationId": "PaymentsController_listPayouts",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payouts listed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List payouts for connected account",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "PaymentsController_createPayout",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePayoutDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Payout created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a payout to the connected account",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/auto-reload": {
      "post": {
        "operationId": "PaymentsController_configureAutoReload",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auto-reload configured successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Configure auto-reload settings",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/balance": {
      "get": {
        "operationId": "PaymentsController_getCreditBalance",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Credit balance retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias: get credit balance",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/check-balance": {
      "post": {
        "operationId": "PaymentsController_checkCreditBalance",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckCreditBalanceDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Credit balance check completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check if organization has enough credits for an action",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/check-reload": {
      "post": {
        "operationId": "PaymentsController_checkAutoReload",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auto-reload check completed"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check and process auto-reload if needed",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/checkout": {
      "post": {
        "operationId": "PaymentsController_checkoutCredits",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurchaseCreditsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Checkout session created for credit purchase"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create credit checkout session (alias route)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/packages": {
      "get": {
        "operationId": "PaymentsController_getCreditPackages",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Credit packages retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get available credit packages",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/purchase": {
      "post": {
        "operationId": "PaymentsController_purchaseCredits",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurchaseCreditsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Payment intent created for credit purchase"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Purchase credits",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/transactions": {
      "get": {
        "operationId": "PaymentsController_getCreditTransactions",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get credit transaction history (paged)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/credits/wallet": {
      "get": {
        "operationId": "PaymentsController_getCreditWallet",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Credit wallet retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get credit wallet balance and summary",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/customers": {
      "post": {
        "operationId": "PaymentsController_createCustomer",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Customer created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create Stripe customer",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/customers/{id}": {
      "get": {
        "operationId": "PaymentsController_getCustomer",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Customer retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Stripe customer",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoice-preview": {
      "get": {
        "operationId": "PaymentsController_getInvoicePreview",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Preview data retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get invoice preview with sample data",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoice-templates": {
      "get": {
        "operationId": "PaymentsController_getInvoiceTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get available invoice templates",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices": {
      "get": {
        "operationId": "PaymentsController_getInvoices",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoices retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all invoices",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "PaymentsController_createInvoice",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Invoice created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create invoice",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/branding": {
      "get": {
        "operationId": "PaymentsController_getInvoiceBranding",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Branding settings retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get invoice branding settings",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "PaymentsController_updateInvoiceBranding",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceBrandingDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Branding settings updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update invoice branding settings",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/builder": {
      "post": {
        "operationId": "PaymentsController_createInvoiceBuilder",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Invoice created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create invoice using builder (free feature)",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}": {
      "delete": {
        "operationId": "PaymentsController_deleteInvoice",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice deleted successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete invoice",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/finalize": {
      "post": {
        "operationId": "PaymentsController_finalizeInvoice",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice finalized successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finalize invoice",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/mark-paid": {
      "post": {
        "operationId": "PaymentsController_markInvoicePaid",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice marked as paid successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Manually mark invoice as paid",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/payment-link": {
      "post": {
        "operationId": "PaymentsController_generatePaymentLink",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payment link generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate payment link for invoice",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/payment-status": {
      "get": {
        "operationId": "PaymentsController_getInvoicePaymentStatus",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payment status retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get invoice payment status",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/pdf": {
      "get": {
        "operationId": "PaymentsController_generateInvoicePdf",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate invoice PDF",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/send": {
      "post": {
        "operationId": "PaymentsController_sendInvoice",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice sent successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send invoice",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/invoices/{id}/send-email": {
      "post": {
        "operationId": "PaymentsController_sendInvoiceEmail",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice email sent successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send invoice via email",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/payment-links": {
      "post": {
        "operationId": "PaymentsController_createPaymentLink",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentLinkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Payment link created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create payment link",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/payment-methods": {
      "get": {
        "operationId": "PaymentsController_listPaymentMethods",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Payment methods retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List saved payment methods for auto-reload",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "PaymentsController_savePaymentMethod",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentMethodDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Payment method saved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save payment method for auto-reload",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/payment-methods/setup-intent": {
      "post": {
        "operationId": "PaymentsController_createSetupIntent",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Setup intent created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create setup intent for saving payment method",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/payment-methods/{id}/default": {
      "post": {
        "operationId": "PaymentsController_setDefaultPaymentMethod",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Default payment method updated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set a payment method as default for auto-reload",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/refunds": {
      "post": {
        "operationId": "PaymentsController_createRefund",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Refund created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create refund",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/subscriptions": {
      "delete": {
        "operationId": "PaymentsController_cancelSubscription",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Subscription cancelled successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel subscription",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "PaymentsController_createSubscription",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Subscription created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create subscription",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/subscriptions/billing-portal": {
      "post": {
        "operationId": "PaymentsController_getBillingPortalUrl",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Billing portal URL generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get billing portal URL",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/subscriptions/current": {
      "get": {
        "operationId": "PaymentsController_getCurrentSubscription",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Current subscription retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get current subscription",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/subscriptions/plans": {
      "get": {
        "operationId": "PaymentsController_getSubscriptionPlans",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Subscription plans retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get available subscription plans",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/subscriptions/usage": {
      "get": {
        "operationId": "PaymentsController_getSubscriptionUsage",
        "parameters": [
          {
            "in": "query",
            "name": "startDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription usage retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get subscription usage analytics",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/subscriptions/{planId}": {
      "put": {
        "operationId": "PaymentsController_updateSubscription",
        "parameters": [
          {
            "in": "path",
            "name": "planId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update subscription plan",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/payments/upload/logo": {
      "post": {
        "operationId": "PaymentsController_uploadLogo",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Logo uploaded successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload logo for invoice branding",
        "tags": [
          "Payments"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/public/book/{bookingKey}/appointments": {
      "post": {
        "description": "Create a public booking appointment.",
        "operationId": "PublicBookingController_createPublicAppointmentByBookingKey",
        "parameters": [
          {
            "description": "Calendar booking key",
            "in": "path",
            "name": "bookingKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Widget key for analytics",
            "in": "header",
            "name": "x-widget-key",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Widget session identifier",
            "in": "header",
            "name": "x-session-id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Appointment created successfully"
          }
        },
        "summary": "Create appointment via public booking (booking key)",
        "tags": [
          "Booking"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/public/book/{bookingKey}/slots": {
      "get": {
        "description": "List available public booking slots.",
        "operationId": "PublicBookingController_getAvailableSlotsByBookingKey",
        "parameters": [
          {
            "description": "Calendar booking key",
            "in": "path",
            "name": "bookingKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Service offering ID",
            "in": "query",
            "name": "serviceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Date in YYYY-MM-DD format",
            "in": "query",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Staff ID (optional)",
            "in": "query",
            "name": "staffId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Client timezone (IANA name)",
            "in": "query",
            "name": "timezone",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-widget-key",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-session-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Slot availability returned"
          }
        },
        "summary": "Get available booking slots by booking key",
        "tags": [
          "Booking"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/public/book/{bookingKey}/upload-photos": {
      "post": {
        "description": "Upload photos during public booking intake.",
        "operationId": "PublicBookingController_uploadBookingPhotos",
        "parameters": [
          {
            "description": "Calendar booking key",
            "in": "path",
            "name": "bookingKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Widget session identifier",
            "in": "header",
            "name": "x-session-id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "files": {
                    "description": "Up to 5 image files",
                    "items": {
                      "format": "binary",
                      "type": "string"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "files"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Photos uploaded successfully"
          }
        },
        "summary": "Upload booking photos through Filestack (backend proxy)",
        "tags": [
          "Booking"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews": {
      "get": {
        "operationId": "ReviewsController_list",
        "parameters": [
          {
            "description": "Page number (1-indexed)",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "description": "Page size",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 200,
              "type": "number"
            }
          },
          {
            "description": "Filter by workflow status",
            "in": "query",
            "name": "workflowStatus",
            "required": false,
            "schema": {
              "enum": [
                "new",
                "needs_response",
                "responded",
                "resolved"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter by assignee user id",
            "in": "query",
            "name": "assignedToId",
            "required": false,
            "schema": {
              "example": "usr_123",
              "type": "string"
            }
          },
          {
            "description": "Filter by review source/provider",
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "example": "google",
              "type": "string"
            }
          },
          {
            "description": "Filter by location id",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "example": "loc_123",
              "type": "string"
            }
          },
          {
            "description": "Exact star rating (1-5)",
            "in": "query",
            "name": "rating",
            "required": false,
            "schema": {
              "example": 5,
              "type": "number"
            }
          },
          {
            "description": "Full-text search on author/title/body",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "example": "late",
              "type": "string"
            }
          },
          {
            "description": "Filter by specific listing connection IDs (comma separated or repeated query params)",
            "in": "query",
            "name": "connectionIds",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "data": [],
                    "pagination": {
                      "limit": 25,
                      "page": 1,
                      "pages": 1,
                      "total": 0
                    }
                  }
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List reviews for the Reviews Inbox",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/counts": {
      "get": {
        "operationId": "ReviewsController_counts",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get review inbox counts for badges/filters",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/import": {
      "post": {
        "operationId": "ReviewsController_import",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportReviewsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Import reviews from external sources (e.g., Trustpilot/Clutch) via API",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/ingest": {
      "post": {
        "operationId": "ReviewsController_triggerIngestion",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TriggerReviewIngestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Trigger review ingestion for all or specific listing connections",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/metrics/summary": {
      "get": {
        "operationId": "ReviewsController_metrics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get basic aggregate metrics for the Reviews dashboard (proxy)",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/providers": {
      "get": {
        "operationId": "ReviewsController_listProviders",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ReviewProviderDto"
                  },
                  "type": "array"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List supported review providers/sources and their capabilities",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/request-settings": {
      "get": {
        "operationId": "ReviewsController_getRequestSettings",
        "parameters": [
          {
            "in": "query",
            "name": "locationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewSettingsDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get review request settings for organization or location",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "ReviewsController_updateRequestSettings",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewSettingsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewSettingsDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update review request settings",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/requests": {
      "get": {
        "operationId": "ReviewsController_listReviewRequests",
        "parameters": [
          {
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "email",
                "sms"
              ],
              "type": "string"
            }
          },
          {
            "description": "Supports both internal statuses and Marketing Suite spec statuses",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "queued",
                "sending",
                "sent",
                "failed",
                "pending",
                "sent",
                "opened",
                "clicked",
                "reviewed",
                "failed"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter by contact identifier",
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by location identifier",
            "in": "query",
            "name": "locationId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by appointment identifier",
            "in": "query",
            "name": "appointmentId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by job identifier",
            "in": "query",
            "name": "jobId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-01-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-01-31T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "description": "Search contact name, email, or phone",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "take",
            "required": false,
            "schema": {
              "default": 50,
              "example": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "skip",
            "required": false,
            "schema": {
              "example": 0,
              "minimum": 0,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": "createdAt",
              "enum": [
                "createdAt",
                "sendAfter",
                "sentAt"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "order",
            "required": false,
            "schema": {
              "default": "desc",
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Only include requests that are scheduled to send in the future",
            "in": "query",
            "name": "includeScheduledOnly",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ReviewRequestResponseDto"
                  },
                  "type": "array"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List review requests",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "ReviewsController_createReviewRequest",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReviewRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CreateReviewRequestResponseDto"
                  },
                  "type": "array"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create manual review request(s)",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/{reviewId}": {
      "get": {
        "operationId": "ReviewsController_getOne",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewInboxItemDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a single review (Inbox detail)",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/{reviewId}/comments": {
      "get": {
        "operationId": "ReviewsController_listComments",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ReviewCommentDto"
                  },
                  "type": "array"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List internal comments/notes for a review",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "ReviewsController_addComment",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReviewCommentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewCommentDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add an internal comment/note to a review",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/{reviewId}/reply": {
      "patch": {
        "operationId": "ReviewsController_updateReply",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewReplyDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save a reply to a review (and mark responded). Publishing is provider-dependent.",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/{reviewId}/reply-draft": {
      "post": {
        "operationId": "ReviewsController_generateReplyDraft",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateReviewReplyDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate an AI reply draft for a review (manual or publish flow)",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/{reviewId}/view": {
      "post": {
        "operationId": "ReviewsController_markViewed",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark a review as viewed (org-level, MVP)",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/reviews/{reviewId}/workflow": {
      "patch": {
        "operationId": "ReviewsController_updateWorkflow",
        "parameters": [
          {
            "in": "path",
            "name": "reviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewWorkflowDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewInboxItemDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update review workflow fields (status/assignee)",
        "tags": [
          "Reviews"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff": {
      "get": {
        "operationId": "StaffController_findAll",
        "parameters": [
          {
            "in": "query",
            "name": "isActive",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Staff members retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all staff members",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "StaffController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStaffDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Staff member created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new staff member",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}": {
      "delete": {
        "operationId": "StaffController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Staff member deactivated successfully"
          },
          "404": {
            "description": "Staff member not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a staff member",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "StaffController_findOne",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Staff member retrieved successfully"
          },
          "404": {
            "description": "Staff member not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a staff member by ID",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "StaffController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateStaffDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Staff member updated successfully"
          },
          "404": {
            "description": "Staff member not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a staff member",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}/availability": {
      "get": {
        "operationId": "StaffController_getAvailability",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Availability retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get staff member availability for a date",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}/breaks": {
      "get": {
        "operationId": "StaffController_getBreaks",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get staff breaks",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "StaffController_createBreak",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBreakDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create staff break",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}/breaks/{breakId}": {
      "delete": {
        "operationId": "StaffController_deleteBreak",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "breakId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete staff break",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}/time-off": {
      "get": {
        "operationId": "StaffController_getTimeOff",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get time off requests for staff",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "StaffController_createTimeOff",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTimeOffDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create time off request",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}/time-off/{timeOffId}": {
      "delete": {
        "operationId": "StaffController_deleteTimeOff",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "timeOffId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete time off request",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "StaffController_updateTimeOff",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "timeOffId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTimeOffDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update time off request",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/staff/{id}/working-hours": {
      "get": {
        "operationId": "StaffController_getWorkingHours",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get weekly working hours for staff",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "StaffController_setWorkingHours",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetWorkingHoursDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set working hours for staff",
        "tags": [
          "Calendar"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys": {
      "get": {
        "operationId": "SurveysController_list",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List surveys (alias to survey templates)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "SurveysController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSurveyFrontendDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create survey (template)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/campaigns": {
      "get": {
        "operationId": "SurveyCampaignsController_listCampaigns",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortOrder",
            "required": false,
            "schema": {
              "default": "desc",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "templateId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "example": "active",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List survey campaigns",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "SurveyCampaignsController_createCampaign",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSurveyCampaignDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new survey campaign",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/campaigns/{campaignId}": {
      "get": {
        "operationId": "SurveyCampaignsController_getCampaign",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get campaign with triggers",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "SurveyCampaignsController_updateCampaign",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSurveyCampaignDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update campaign configuration",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/campaigns/{campaignId}/triggers": {
      "post": {
        "operationId": "SurveyCampaignsController_createTrigger",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSurveyTriggerDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create trigger for campaign",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/campaigns/{campaignId}/triggers/{triggerId}": {
      "put": {
        "operationId": "SurveyCampaignsController_updateTrigger",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "triggerId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSurveyTriggerDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update trigger configuration",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/invitations": {
      "get": {
        "operationId": "SurveyInvitationsController_listInvitations",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortOrder",
            "required": false,
            "schema": {
              "default": "desc",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "templateId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "appointmentId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "QUEUED",
                "SENT",
                "DELIVERED",
                "RESPONDED",
                "BOUNCED",
                "FAILED",
                "CANCELLED"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List survey invitations",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/invitations/manual": {
      "post": {
        "operationId": "SurveyInvitationsController_createManualInvitation",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateManualSurveyInvitationDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a manual survey invitation",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/invitations/{invitationId}": {
      "get": {
        "operationId": "SurveyInvitationsController_getInvitation",
        "parameters": [
          {
            "in": "path",
            "name": "invitationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a specific invitation",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/invitations/{invitationId}/cancel": {
      "patch": {
        "operationId": "SurveyInvitationsController_cancelInvitation",
        "parameters": [
          {
            "in": "path",
            "name": "invitationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel an invitation",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/invitations/{invitationId}/reschedule": {
      "patch": {
        "operationId": "SurveyInvitationsController_rescheduleInvitation",
        "parameters": [
          {
            "in": "path",
            "name": "invitationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RescheduleSurveyInvitationDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reschedule a queued invitation",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/invitations/{invitationId}/resend": {
      "post": {
        "operationId": "SurveyInvitationsController_resendInvitation",
        "parameters": [
          {
            "in": "path",
            "name": "invitationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resend an invitation",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/metrics/breakdown": {
      "get": {
        "operationId": "SurveyMetricsController_getBreakdown",
        "parameters": [
          {
            "in": "query",
            "name": "templateId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO string start datetime",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO string end datetime",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "dimension",
            "required": true,
            "schema": {
              "enum": [
                "channel",
                "template"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get survey metrics breakdown by dimension",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/metrics/overview": {
      "get": {
        "operationId": "SurveyMetricsController_getOverview",
        "parameters": [
          {
            "in": "query",
            "name": "templateId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO string start datetime",
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO string end datetime",
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get survey performance overview",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/responses": {
      "get": {
        "operationId": "SurveyResponsesController_listResponses",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortOrder",
            "required": false,
            "schema": {
              "default": "desc",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "templateId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "appointmentId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "minScore",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "maxScore",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": false,
            "schema": {
              "example": "2025-01-01",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": false,
            "schema": {
              "example": "2025-01-31",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List survey responses",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "SurveyResponsesController_createResponse",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSurveyResponseDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record a response manually (e.g., admin input)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/responses/{responseId}": {
      "get": {
        "operationId": "SurveyResponsesController_getResponse",
        "parameters": [
          {
            "in": "path",
            "name": "responseId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a single response",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/templates": {
      "get": {
        "operationId": "SurveyTemplatesController_listTemplates",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortBy",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sortOrder",
            "required": false,
            "schema": {
              "default": "desc",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "scoreType",
            "required": false,
            "schema": {
              "enum": [
                "NPS",
                "CSAT",
                "CES",
                "CUSTOM"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "EMAIL",
                "SMS",
                "WHATSAPP",
                "CHAT_WIDGET",
                "TICKET",
                "CALL_IVR"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "isActive",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SurveyTemplateListResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List survey templates for the organization",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "operationId": "SurveyTemplatesController_createTemplate",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSurveyTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SurveyTemplateResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new survey template",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/templates/{templateId}": {
      "get": {
        "operationId": "SurveyTemplatesController_getTemplate",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SurveyTemplateResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a single survey template",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "operationId": "SurveyTemplatesController_updateTemplate",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSurveyTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SurveyTemplateResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update an existing survey template",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/templates/{templateId}/duplicate": {
      "post": {
        "operationId": "SurveyTemplatesController_duplicateTemplate",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DuplicateSurveyTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SurveyTemplateResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Duplicate a survey template",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/templates/{templateId}/status": {
      "patch": {
        "operationId": "SurveyTemplatesController_updateTemplateStatus",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSurveyTemplateStatusDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SurveyTemplateResponseDto"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enable or disable a survey template",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/{id}": {
      "delete": {
        "operationId": "SurveysController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete survey (template)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "SurveysController_get",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get survey (template) with questions",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "SurveysController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSurveyFrontendDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update survey (template)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/{id}/publish": {
      "post": {
        "operationId": "SurveysController_publish",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish survey (generate share URL + embed code)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/surveys/{id}/responses": {
      "get": {
        "operationId": "SurveysController_listResponses",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "startDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "endDate",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List survey responses (by template id)",
        "tags": [
          "Surveys"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/tasks": {
      "get": {
        "description": "Retrieves a paginated list of tasks for the current organization. Supports filtering by ownership, status, priority, and related CRM records.",
        "operationId": "TasksController_findAll",
        "parameters": [
          {
            "description": "Filter by task status (e.g., OPEN, COMPLETED).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by priority. Accepts values defined in the task model.",
            "in": "query",
            "name": "priority",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict to tasks linked to a specific contact.",
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict to tasks linked to a specific company.",
            "in": "query",
            "name": "companyId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict to tasks linked to a specific deal.",
            "in": "query",
            "name": "dealId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only include tasks owned by the provided teammate ID.",
            "in": "query",
            "name": "ownerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum tasks to return. Defaults to service-level pagination.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Number of records to skip before returning results.",
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tasks retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all tasks",
        "tags": [
          "CRM Tasks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Creates a CRM task assigned to a teammate or contact. Tasks can be tied to contacts, companies, or deals for follow-up.",
        "operationId": "TasksController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTaskDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Task created successfully"
          },
          "400": {
            "description": "Invalid input data"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new task",
        "tags": [
          "CRM Tasks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/tasks/count": {
      "get": {
        "description": "Returns a filtered count of tasks for badge/notification use cases. Combine filters to match what a user sees in list views.",
        "operationId": "TasksController_getCount",
        "parameters": [
          {
            "description": "Filter by task status (e.g., OPEN for TODOs).",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by task priority (e.g., HIGH, MEDIUM, LOW).",
            "in": "query",
            "name": "priority",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict to tasks related to a contact.",
            "in": "query",
            "name": "contactId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict to tasks related to a company.",
            "in": "query",
            "name": "companyId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict to tasks related to a deal.",
            "in": "query",
            "name": "dealId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only count tasks owned by the provided teammate ID.",
            "in": "query",
            "name": "ownerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task count retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get task count (useful for notifications/badges)",
        "tags": [
          "CRM Tasks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/tasks/{id}": {
      "delete": {
        "description": "Deletes a task permanently. Consider using status updates when historical auditing is required.",
        "operationId": "TasksController_remove",
        "parameters": [
          {
            "description": "Task identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task deleted successfully"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete task",
        "tags": [
          "CRM Tasks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "description": "Retrieves details for a single task, including related CRM entities, ensuring it belongs to the organization in context.",
        "operationId": "TasksController_findOne",
        "parameters": [
          {
            "description": "Task identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task retrieved successfully"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get task by ID",
        "tags": [
          "CRM Tasks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Performs a partial update on a task. Use to mark completion, adjust due dates, or reassign ownership.",
        "operationId": "TasksController_update",
        "parameters": [
          {
            "description": "Task identifier",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTaskDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Task updated successfully"
          },
          "404": {
            "description": "Task not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update task",
        "tags": [
          "CRM Tasks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/voice/browser/token": {
      "post": {
        "description": "Frontend uses this token with Twilio Voice JS to place a browser call into the org’s primary AI phone number.",
        "operationId": "VoiceBrowserController_createClientToken",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a Twilio Voice Client token (browser WebRTC calling)",
        "tags": [
          "Voice"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/voice/preview/voices": {
      "get": {
        "description": "Returns the UI voice catalog supported by POST /v1/voice/preview. Use this to populate the voice picker instead of hard-coding IDs on the frontend.",
        "operationId": "VoicePreviewController_listVoices",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available voice preview voices",
        "tags": [
          "Voice"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/webhooks/deliveries": {
      "get": {
        "description": "Returns the canonical paginated envelope `{ data, meta }` (BE-10). Same shape as `GET /v1/webhooks/endpoints` so FE never has to branch on which webhooks list it is rendering.",
        "operationId": "WebhooksController_getDeliveries",
        "parameters": [
          {
            "in": "query",
            "name": "webhookId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "eventType",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "page",
                        "limit",
                        "totalPages"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Paginated webhook deliveries."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get webhook delivery history",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/webhooks/deliveries/{id}/replay": {
      "post": {
        "description": "Replay a webhook delivery.",
        "operationId": "WebhooksController_replayDelivery",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook replay initiated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replay webhook delivery",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/webhooks/endpoints": {
      "get": {
        "description": "Returns the canonical paginated envelope `{ data, meta }`. The `secret` field is **never** returned in plaintext on list/findOne — only `secretLast4` is exposed. Plaintext is returned exactly once, on `POST /webhooks/endpoints` create.",
        "operationId": "WebhooksController_findAllEndpoints",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpointResponseDto"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "page",
                        "limit",
                        "totalPages"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Paginated webhook endpoints."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all webhook endpoints",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Returns the webhook with the plaintext `secret` — **the only surface that ever exposes plaintext.** Copy it now; every subsequent read returns `secretLast4` instead.",
        "operationId": "WebhooksController_createEndpoint",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointCreateResponseDto"
                }
              }
            },
            "description": "Webhook endpoint created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/webhooks/endpoints/{id}": {
      "delete": {
        "description": "Manage a webhook endpoint.",
        "operationId": "WebhooksController_removeEndpoint",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook endpoint deactivated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "description": "`secret` is redacted to `secretLast4` on this response. The plaintext secret is only available on create.",
        "operationId": "WebhooksController_findOneEndpoint",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointResponseDto"
                }
              }
            },
            "description": "Webhook endpoint retrieved successfully"
          },
          "404": {
            "description": "Webhook endpoint not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get webhook endpoint by ID",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "description": "Manage a webhook endpoint.",
        "operationId": "WebhooksController_updateEndpoint",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Webhook endpoint updated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/webhooks/endpoints/{id}/test": {
      "post": {
        "description": "Send a test event to a webhook endpoint.",
        "operationId": "WebhooksController_testEndpoint",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook test initiated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Test webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-serviceagent-stability": "stable",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflow-actions": {
      "get": {
        "operationId": "WorkflowActionsController_getActions",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Workflow actions retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List available workflow actions",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflow-templates": {
      "get": {
        "operationId": "LegacyWorkflowTemplatesController_getWorkflowTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Workflow templates retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List workflow templates",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflow-templates/{id}": {
      "get": {
        "operationId": "LegacyWorkflowTemplatesController_getWorkflowTemplate",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow template retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Workflow template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow template",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflow-templates/{id}/use": {
      "post": {
        "operationId": "LegacyWorkflowTemplatesController_useWorkflowTemplate",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Workflow created successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Workflow template not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create workflow from template",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows": {
      "get": {
        "description": "Returns the canonical paginated envelope `{ data, meta: { total, page, limit, totalPages } }`. The flat keys (`total`, `page`, `limit`, `totalPages`) are also echoed at the root for one release as a legacy alias — prefer reading from `meta`. By default returns ALL workflows including drafts; pass `?isActive=true` to filter only active.",
        "operationId": "WorkflowsController_findAll",
        "parameters": [
          {
            "in": "query",
            "name": "isActive",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "limit": {
                      "deprecated": true,
                      "type": "integer"
                    },
                    "meta": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "page",
                        "limit",
                        "totalPages"
                      ],
                      "type": "object"
                    },
                    "page": {
                      "deprecated": true,
                      "type": "integer"
                    },
                    "total": {
                      "deprecated": true,
                      "type": "integer"
                    },
                    "totalPages": {
                      "deprecated": true,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "data",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Paginated list of workflows."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get all workflows",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "post": {
        "description": "Returns the bare workflow object. The legacy `{ workflow: {...} }` wrapper has been removed — read fields directly off the response (`response.id`, `response.name`, ...).",
        "operationId": "WorkflowsController_create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWorkflowDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "properties": {
                    "category": {
                      "nullable": true,
                      "type": "string"
                    },
                    "conversationCount": {
                      "type": "integer"
                    },
                    "createdAt": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "description": {
                      "nullable": true,
                      "type": "string"
                    },
                    "edges": {
                      "items": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "hasAiHistory": {
                      "type": "boolean"
                    },
                    "id": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "isActive": {
                      "type": "boolean"
                    },
                    "locationId": {
                      "format": "uuid",
                      "nullable": true,
                      "type": "string"
                    },
                    "metadata": {
                      "additionalProperties": true,
                      "nullable": true,
                      "type": "object"
                    },
                    "name": {
                      "type": "string"
                    },
                    "nodes": {
                      "items": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "organizationId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "source": {
                      "nullable": true,
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "DRAFT",
                        "ACTIVE",
                        "PAUSED",
                        "ARCHIVED"
                      ],
                      "type": "string"
                    },
                    "templateId": {
                      "nullable": true,
                      "type": "string"
                    },
                    "trigger": {
                      "properties": {
                        "config": {
                          "additionalProperties": true,
                          "type": "object"
                        },
                        "type": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "triggerConfig": {
                      "additionalProperties": true,
                      "type": "object"
                    },
                    "triggerType": {
                      "enum": [
                        "MANUAL",
                        "SCHEDULED",
                        "EVENT",
                        "WEBHOOK"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "format": "date-time",
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "organizationId",
                    "isActive",
                    "status",
                    "nodes",
                    "edges"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Workflow created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/advisor/apply": {
      "post": {
        "operationId": "WorkflowAdvisorController_apply",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyWorkflowSuggestionDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Workflow created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a workflow from a suggestion/template",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/advisor/suggest": {
      "post": {
        "operationId": "WorkflowAdvisorController_suggest",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SuggestWorkflowDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow suggestions returned successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Suggest workflows based on a natural language prompt",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/ai/generate": {
      "post": {
        "operationId": "WorkflowsController_generateWithAi",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateWorkflowWithAiDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow generated successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate workflow graph from natural language prompt",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/ai/refine": {
      "post": {
        "operationId": "WorkflowsController_refineWithAi",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefineWorkflowWithAiDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow refined successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Refine an existing workflow with AI instruction",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/ai/validate": {
      "post": {
        "operationId": "WorkflowsController_validateWithAi",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateWorkflowWithAiDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow validation completed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Validate AI-generated or edited workflow graph",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/runs/failed": {
      "get": {
        "operationId": "WorkflowsController_listFailedRuns",
        "parameters": [
          {
            "in": "query",
            "name": "workflowId",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List failed workflow runs (DLQ-like inbox)",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/runs/{runId}": {
      "get": {
        "operationId": "WorkflowsController_getRun",
        "parameters": [
          {
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow run retrieved successfully"
          },
          "404": {
            "description": "Workflow run not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a workflow run by ID",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/runs/{runId}/cancel": {
      "post": {
        "operationId": "WorkflowsController_cancelRun",
        "parameters": [
          {
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow run cancelled successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel a workflow run",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/runs/{runId}/retry": {
      "post": {
        "operationId": "WorkflowsController_retryRun",
        "parameters": [
          {
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RetryWorkflowRunDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Retry a workflow run by creating a new run",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/schema": {
      "get": {
        "operationId": "WorkflowsController_getWorkflowSchema",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Workflow schema retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow builder schema for AI + UI",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates": {
      "get": {
        "operationId": "WorkflowTemplatesController_getTemplateGallery",
        "parameters": [
          {
            "description": "Industry slug. Defaults to org industry or general.",
            "in": "query",
            "name": "industry",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional category filter.",
            "in": "query",
            "name": "category",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Free-text search over template name/description/tags.",
            "in": "query",
            "name": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Max templates to return",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow template gallery retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow template gallery for current organization",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/batch": {
      "post": {
        "operationId": "WorkflowTemplatesController_batchInsert",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchWorkflowTemplatesDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upsert workflow templates in batch",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/batch-create": {
      "post": {
        "operationId": "WorkflowTemplatesController_batchCreate",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchCreateTemplatesRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Workflows created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Batch create workflows from templates for organization",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/categories/{industry}": {
      "get": {
        "operationId": "WorkflowTemplatesController_getCategoriesByIndustry",
        "parameters": [
          {
            "in": "path",
            "name": "industry",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Categories retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow categories for industry",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/sentiment-templates/create": {
      "post": {
        "operationId": "WorkflowTemplatesController_createSentimentTemplates",
        "parameters": [
          {
            "in": "query",
            "name": "activate",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sentiment templates created successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create all 5 sentiment workflow templates for organization",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/{id}/executions": {
      "get": {
        "operationId": "WorkflowTemplatesController_getExecutionHistory",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Execution history retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow execution history",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/{id}/test": {
      "post": {
        "operationId": "WorkflowTemplatesController_testWorkflow",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow test completed successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Test workflow execution",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/{industry}": {
      "get": {
        "operationId": "WorkflowTemplatesController_getTemplatesByIndustry",
        "parameters": [
          {
            "in": "path",
            "name": "industry",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get industry-specific workflow templates",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/templates/{templateId}/instantiate": {
      "post": {
        "operationId": "WorkflowTemplatesController_instantiateTemplate",
        "parameters": [
          {
            "in": "path",
            "name": "templateId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InstantiateWorkflowTemplateDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Instantiate a workflow from a template",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}": {
      "delete": {
        "description": "BE-8: soft-archive. Sets `isActive=false` AND `status=ARCHIVED`. The workflow is hidden from the default `GET /workflows` listing only if the caller filters by `?status=ACTIVE` or `?isActive=true`. Use `POST /:id/deactivate` instead if you want the workflow to remain editable as a paused row.",
        "operationId": "WorkflowsController_remove",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow archived successfully"
          },
          "403": {
            "description": "Forbidden - insufficient permissions"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Archive a workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "get": {
        "operationId": "WorkflowsController_findOne",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow retrieved successfully"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a workflow by ID",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "patch": {
        "operationId": "WorkflowsController_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWorkflowDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow updated successfully"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      },
      "put": {
        "description": "Full-save route for workflow builders. Uses the same validation and persistence path as PATCH /workflows/:id.",
        "operationId": "WorkflowsController_replace",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWorkflowDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow updated successfully"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace/update a workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/activate": {
      "post": {
        "description": "BE-8 + BE-15: explicit, idempotent activation. Sets `isActive=true` AND `status=ACTIVE` atomically — preferred over `PATCH /:id { isActive: true }` because it cannot drift the two fields. Pre-flight validation (BE-15): the workflow graph is validated using the same rules as `POST /v1/workflows/ai/validate`. If the graph has unresolved errors (no trigger, orphan nodes, missing required action config, etc.), this endpoint returns 400 with `code: WORKFLOW_NOT_ACTIVATABLE` and a structured `details[]` array the FE can map back to specific nodes. Idempotent: calling on an already-active workflow returns 200 with the workflow unchanged (skips validation).",
        "operationId": "WorkflowsController_activate",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow activated successfully"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "code": {
                      "description": "Stable error code. Use this in FE error handling instead of matching on message strings.",
                      "example": "WORKFLOW_NOT_ACTIVATABLE",
                      "type": "string"
                    },
                    "details": {
                      "description": "Per-issue details for `WORKFLOW_NOT_ACTIVATABLE`. Map back to nodes/edges in the builder UI via `nodeId` / `edgeId`. Same issue codes as `POST /v1/workflows/ai/validate`.",
                      "items": {
                        "properties": {
                          "code": {
                            "description": "Stable issue code. See FE_WIRING_WORKFLOWS.md for the catalog.",
                            "example": "WORKFLOW_TRIGGER_COUNT",
                            "type": "string"
                          },
                          "edgeId": {
                            "nullable": true,
                            "type": "string"
                          },
                          "field": {
                            "example": "config.message",
                            "nullable": true,
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "nodeId": {
                            "nullable": true,
                            "type": "string"
                          },
                          "severity": {
                            "enum": [
                              "error"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "message",
                          "severity"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "message": {
                      "example": "Workflow has unresolved validation errors and cannot be activated.",
                      "type": "string"
                    },
                    "statusCode": {
                      "enum": [
                        400
                      ],
                      "type": "integer"
                    }
                  },
                  "required": [
                    "statusCode",
                    "message"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Activation blocked. Either the trigger type is not allowed on the current plan, the workflow is a system template, or — most commonly — the graph has unresolved validation errors (`code: WORKFLOW_NOT_ACTIVATABLE`)."
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Activate a workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/deactivate": {
      "post": {
        "description": "BE-8: explicit, idempotent deactivation. Sets `isActive=false` AND `status=PAUSED` atomically. Idempotent: calling on an already-paused workflow returns 200 unchanged. Does NOT change `ARCHIVED` workflows.",
        "operationId": "WorkflowsController_deactivate",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow deactivated successfully"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Deactivate a workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/dry-run": {
      "post": {
        "description": "Side-effect-free simulator for the workflow editor. Loads the graph, walks dependency order, evaluates simple condition nodes, and reports which action nodes would execute. Does not enqueue a run or call external services.",
        "operationId": "WorkflowsController_dryRun",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkflowDryRunDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Workflow dry-run completed successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dry-run a workflow with synthetic trigger data",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/duplicate": {
      "post": {
        "operationId": "WorkflowsController_duplicate",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DuplicateWorkflowDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Workflow duplicated successfully"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Duplicate a workflow",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/logs": {
      "get": {
        "operationId": "WorkflowLogsController_getWorkflowLogs",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow logs retrieved successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Workflow not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow logs",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/runs": {
      "get": {
        "operationId": "WorkflowsController_getRuns",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {}
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow runs retrieved successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get workflow runs",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{id}/trigger": {
      "post": {
        "operationId": "WorkflowsController_trigger",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow triggered successfully"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Trigger a workflow manually",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    },
    "/v1/workflows/{workflowId}/executions/{executionId}": {
      "get": {
        "operationId": "WorkflowsController_getExecution",
        "parameters": [
          {
            "in": "path",
            "name": "workflowId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "executionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow execution retrieved successfully"
          },
          "404": {
            "description": "Workflow execution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a single workflow execution (frontend polling contract)",
        "tags": [
          "Workflows"
        ],
        "x-serviceagent-stability": "beta",
        "x-serviceagent-visibility": "public"
      }
    }
  },
  "servers": [
    {
      "description": "Production",
      "url": "https://process.serviceagent.ai/v1"
    }
  ],
  "tags": [
    {
      "description": "Demo workspace provisioning and claim flows.",
      "name": "Install"
    },
    {
      "description": "Public chat widget configuration and session APIs.",
      "name": "Widget"
    },
    {
      "description": "Public calendar booking APIs.",
      "name": "Booking"
    },
    {
      "description": "Company account management for CRM integrations.",
      "name": "CRM Companies"
    },
    {
      "description": "Contact records, enrichment, import, filters, and customer intelligence.",
      "name": "CRM Contacts"
    },
    {
      "description": "Sales pipeline and deal management.",
      "name": "CRM Deals"
    },
    {
      "description": "CRM activity and timeline records.",
      "name": "CRM Activities"
    },
    {
      "description": "Task management and follow-up workflows.",
      "name": "CRM Tasks"
    },
    {
      "description": "Appointments, staff, availability, and scheduling management.",
      "name": "Calendar"
    },
    {
      "description": "Location records, default locations, staff assignment, and availability.",
      "name": "Locations"
    },
    {
      "description": "AI agent configuration, channels, publishing, test runs, and voice config.",
      "name": "AI Agents"
    },
    {
      "description": "AI context, profile sync, service sync, and knowledge search.",
      "name": "AI Brain"
    },
    {
      "description": "Knowledge bases, articles, documents, sync, and search.",
      "name": "Knowledge"
    },
    {
      "description": "Inbox threads, messages, and connected messaging channels.",
      "name": "Inbox"
    },
    {
      "description": "Email messages, templates, attachments, sending, and analytics.",
      "name": "Email"
    },
    {
      "description": "Call records, outbound calls, sentiment, transcripts, and recordings.",
      "name": "Calls"
    },
    {
      "description": "Third-party CRM, calendar, task, and connector management.",
      "name": "Integrations"
    },
    {
      "description": "Workflow definitions, templates, AI generation, runs, and triggers.",
      "name": "Workflows"
    },
    {
      "description": "Survey templates, campaigns, invitations, responses, and metrics.",
      "name": "Surveys"
    },
    {
      "description": "Review management, requests, providers, replies, and workflow actions.",
      "name": "Reviews"
    },
    {
      "description": "Invoices, payment links, customers, methods, credits, and subscriptions.",
      "name": "Payments"
    },
    {
      "description": "Model Context Protocol entry points for AI tools.",
      "name": "MCP"
    },
    {
      "description": "API-key management for server-side integrations.",
      "name": "Auth"
    },
    {
      "description": "Webhook endpoint and delivery management.",
      "name": "Webhooks"
    },
    {
      "description": "Voice session helper APIs. Realtime media uses the documented WSS endpoint.",
      "name": "Voice"
    }
  ],
  "x-serviceagent-docs": {
    "policy": "Only explicitly allowlisted operations and curated developer-platform groups are published. Internal, admin, telemetry, and inbound provider webhook routes are excluded.",
    "source": "openapi.json",
    "visibility": "public"
  }
}
