{"openapi":"3.0.0","paths":{"/v1/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":""}},"security":[{}],"summary":"Get API and dependency health","tags":["App - Health"],"x-rate-limit-exempt":true}},"/v1/channels/kpis":{"get":{"description":"Retrieve aggregated key performance indicators across all channels for the authenticated user.","operationId":"ChannelsController_getAllKpis","parameters":[{"name":"period","required":false,"in":"query","description":"Time period for KPI calculations","schema":{"default":"30d","type":"string","enum":["7d","30d","90d"]}},{"name":"dateFrom","required":false,"in":"query","description":"Custom start date (ISO 8601). Overrides period when both dateFrom and dateTo are provided.","schema":{"example":"2025-01-01","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Custom end date (ISO 8601). Overrides period when both dateFrom and dateTo are provided.","schema":{"example":"2025-01-31","type":"string"}}],"responses":{"200":{"description":"Aggregated KPIs retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelKpisDto"}}}},"401":{"description":"Invalid or missing API key"}},"security":[{"api-key":[]}],"summary":"Get aggregated KPIs for all channels","tags":["Channels"]}},"/v1/channels/{id}/kpis":{"get":{"description":"Retrieve key performance indicators for a specific channel including contacts, messages, broadcasts, and engagement metrics.","operationId":"ChannelsController_getKpis","parameters":[{"name":"id","required":true,"in":"path","description":"Channel ID","schema":{"example":505,"type":"number"}},{"name":"period","required":false,"in":"query","description":"Time period for KPI calculations","schema":{"default":"30d","type":"string","enum":["7d","30d","90d"]}},{"name":"dateFrom","required":false,"in":"query","description":"Custom start date (ISO 8601). Overrides period when both dateFrom and dateTo are provided.","schema":{"example":"2025-01-01","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Custom end date (ISO 8601). Overrides period when both dateFrom and dateTo are provided.","schema":{"example":"2025-01-31","type":"string"}}],"responses":{"200":{"description":"Channel KPIs retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelKpisDto"}}}},"401":{"description":"Invalid or missing API key"},"404":{"description":"Channel not found or does not belong to authenticated user"}},"security":[{"api-key":[]}],"summary":"Get channel KPIs","tags":["Channels"]}},"/v1/channels":{"get":{"description":"Retrieve all messaging channels (WhatsApp, Telegram, SMS) for the authenticated user. Supports pagination and filtering by status and gateway type.","operationId":"ChannelsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by channel lifecycle status. If not provided, returns channels with any status.","schema":{"$ref":"#/components/schemas/ChannelStatus"}},{"name":"gatewayType","required":false,"in":"query","description":"Filter by gateway type ID. If not provided, returns channels with any gateway type.","schema":{"$ref":"#/components/schemas/GatewayType"}},{"name":"search","required":false,"in":"query","description":"Search in channel name","schema":{"example":"Support","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ChannelResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Invalid or missing API key"}},"security":[{"api-key":[]}],"summary":"List all channels","tags":["Channels"]},"post":{"description":"Create a new messaging channel (WhatsApp, Telegram, SMS, etc.)","operationId":"ChannelsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChannelDto"}}}},"responses":{"201":{"description":"Channel created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelResponseDto"}}}},"400":{"description":"Invalid input data"},"401":{"description":"Invalid or missing API key"}},"security":[{"api-key":[]}],"summary":"Create new channel","tags":["Channels"]}},"/v1/channels/{id}":{"get":{"description":"Retrieve detailed information about a specific channel.","operationId":"ChannelsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Channel ID","schema":{"example":505,"type":"number"}}],"responses":{"200":{"description":"Channel details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelResponseDto"}}}},"401":{"description":"Invalid or missing API key"},"404":{"description":"Channel not found or does not belong to authenticated user"}},"security":[{"api-key":[]}],"summary":"Get channel by ID","tags":["Channels"]},"put":{"description":"Update an existing messaging channel","operationId":"ChannelsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Channel ID","schema":{"example":505,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChannelDto"}}}},"responses":{"200":{"description":"Channel updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelResponseDto"}}}},"400":{"description":"Invalid input data"},"401":{"description":"Invalid or missing API key"},"404":{"description":"Channel not found or does not belong to authenticated user"}},"security":[{"api-key":[]}],"summary":"Update channel","tags":["Channels"]}},"/v1/contacts":{"post":{"description":"Create a new recipient (contact) for a channel. Only creates recipients for channels owned by the authenticated user. Phone number must be in E.164 format (e.g., +491701234567).","operationId":"RecipientsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRecipientDto"}}}},"responses":{"201":{"description":"Recipient created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Channel does not belong to user"},"409":{"description":"Conflict - Recipient with this identifier already exists"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new recipient","tags":["Contacts"]},"get":{"description":"Get all recipients with pagination and optional filters. Only returns recipients from channels owned by the authenticated user.","operationId":"RecipientsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":505,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by one or more channel IDs (comma-separated string or array). When set, takes precedence over \"channelId\". Returns recipients belonging to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"optinStatus","required":false,"in":"query","description":"Filter by opt-in status (1 = opted in, 0 = opted out or not opted in)","schema":{"example":1,"type":"number","enum":[0,1]}},{"name":"states","required":false,"in":"query","description":"Filter by derived recipient state (multi-select, comma-separated string or array). Values: 0 = opted out, 1 = opted in, 2 = signed in, 3 = dialog. Returns recipients matching any of the listed states.","schema":{"example":"1,2","type":"string"}},{"name":"isBlocked","required":false,"in":"query","description":"Filter by blocked status (1 = blocked, 0 = not blocked)","schema":{"example":0,"type":"number","enum":[0,1]}},{"name":"search","required":false,"in":"query","description":"Search by name or phone number","schema":{"example":"Max","type":"string"}},{"name":"tagIds","required":false,"in":"query","description":"Filter by tag IDs (comma-separated or array). Returns recipients that have at least one of the specified tags.","schema":{"example":"1,2,3","type":"string"}},{"name":"tagMatchMode","required":false,"in":"query","description":"How to match multiple tags: \"any\" = OR (at least one tag), \"all\" = AND (all tags required)","schema":{"default":"any","example":"any","type":"string","enum":["any","all"]}},{"name":"segmentId","required":false,"in":"query","description":"Filter by segment ID - returns contacts that belong to the segment (based on segment tags)","schema":{"example":42,"type":"number"}},{"name":"spam","required":false,"in":"query","description":"Filter by spam status: true = spam only, false = non-spam only, omit = all contacts","schema":{"example":false,"type":"boolean"}},{"name":"trustLevel","required":false,"in":"query","description":"Filter by trust level (multi-select). Accepts comma-separated string or array. Values: blocked, whitelisted, spam, suspicious, trusted, unknown.","schema":{"example":"blocked,spam","type":"string"}}],"responses":{"200":{"description":"Recipients retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/RecipientResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all recipients","tags":["Contacts"]}},"/v1/contacts/{id}":{"put":{"description":"Update recipient details. Only updates recipients from channels owned by the authenticated user. All fields are optional.","operationId":"RecipientsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Recipient ID","schema":{"example":12345,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecipientDto"}}}},"responses":{"200":{"description":"Recipient updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Recipient does not belong to user"},"404":{"description":"Recipient not found"},"409":{"description":"Conflict - Recipient with this identifier already exists"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing recipient","tags":["Contacts"]},"delete":{"description":"Soft-delete a recipient by setting the deletion timestamp. Only deletes recipients from channels owned by the authenticated user. The recipient data remains in the database but is marked as deleted.","operationId":"RecipientsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Recipient ID","schema":{"example":12345,"type":"number"}}],"responses":{"204":{"description":"Recipient deleted successfully"},"401":{"description":"Unauthorized - Invalid or missing API key"},"404":{"description":"Recipient not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a recipient","tags":["Contacts"]},"get":{"description":"Get recipient by ID. Only returns recipient if it belongs to a channel owned by the authenticated user.","operationId":"RecipientsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Recipient ID","schema":{"example":12345,"type":"number"}}],"responses":{"200":{"description":"Recipient retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientResponseDto"}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"404":{"description":"Recipient not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single recipient","tags":["Contacts"]}},"/v1/contacts/{id}/tags":{"post":{"description":"Assign a tag to a recipient. Only works if both recipient and tag belong to the authenticated user.","operationId":"RecipientsController_addTag","parameters":[{"name":"id","required":true,"in":"path","description":"Recipient ID","schema":{"example":789,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTagDto"}}}},"responses":{"201":{"description":"Tag assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagAssignmentResponseDto"}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"404":{"description":"Recipient or tag not found"},"409":{"description":"Tag already assigned to recipient"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Add tag to recipient","tags":["Contacts"]},"get":{"description":"Get all tags assigned to a recipient. Only returns tags if recipient belongs to the authenticated user.","operationId":"RecipientsController_getRecipientTags","parameters":[{"name":"id","required":true,"in":"path","description":"Recipient ID","schema":{"example":789,"type":"number"}}],"responses":{"200":{"description":"Tags retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TagAssignmentResponseDto"}}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"404":{"description":"Recipient not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get recipient tags","tags":["Contacts"]}},"/v1/contacts/{id}/tags/{tagId}":{"delete":{"description":"Remove a tag assignment from a recipient. Only works if both recipient and tag belong to the authenticated user.","operationId":"RecipientsController_removeTag","parameters":[{"name":"id","required":true,"in":"path","description":"Recipient ID","schema":{"example":789,"type":"number"}},{"name":"tagId","required":true,"in":"path","description":"Tag ID to remove","schema":{"example":123,"type":"number"}}],"responses":{"204":{"description":"Tag removed successfully"},"401":{"description":"Unauthorized - Invalid or missing API key"},"404":{"description":"Recipient, tag, or tag assignment not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Remove tag from recipient","tags":["Contacts"]}},"/v1/messages":{"post":{"description":"Create a new message to be sent to a recipient with optional media attachment. The message is written to the database and will be picked up by the Transmitter worker for sending. Only creates messages for recipients in channels owned by the authenticated user. Supports multipart/form-data for media upload.","operationId":"MessagesController_create","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateMessageDto"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageDto"}}}},"responses":{"201":{"description":"Message created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Recipient does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new message","tags":["Messages"]},"get":{"description":"Get all messages with pagination and optional filters. Only returns messages from recipients in channels owned by the authenticated user.","operationId":"MessagesController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"recipientId","required":false,"in":"query","description":"Filter by recipient ID","schema":{"example":81857,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":505,"type":"number"}},{"name":"direction","required":false,"in":"query","description":"Filter by message direction (s=sent, r=received)","schema":{"example":"r","type":"string","enum":["s","r"]}},{"name":"messageType","required":false,"in":"query","description":"Filter by message type","schema":{"example":"text","type":"string","enum":["text","image","video","audio","document","location","contact","sticker"]}},{"name":"search","required":false,"in":"query","description":"Search in message content","schema":{"example":"hello","type":"string"}},{"name":"spam","required":false,"in":"query","description":"Filter by spam status. true = only spam, false = exclude spam, undefined = all messages","schema":{"example":false,"type":"boolean"}},{"name":"reactionType","required":false,"in":"query","description":"Filter reactions by type. emoji=emoji reactions, button=button replies, text=text replies, all/omit=no filter","schema":{"example":"emoji","type":"string","enum":["all","emoji","button","text"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/MessageResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all messages","tags":["Messages"]}},"/v1/messages/inbox/unread-count":{"get":{"description":"Get the total number of unread received messages (inbox) for the authenticated user.","operationId":"MessagesController_getInboxUnreadCount","parameters":[],"responses":{"200":{"description":"Unread count retrieved successfully","content":{"application/json":{"schema":{"properties":{"unreadCount":{"type":"number","example":12}}}}}},"401":{"description":"Unauthorized"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get unread inbox message count","tags":["Messages"]}},"/v1/messages/bulk/spam":{"put":{"description":"Update the spam status of multiple messages at once. Only updates messages from recipients in channels owned by the authenticated user. Maximum 100 messages per request.","operationId":"MessagesController_bulkToggleSpam","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkMarkSpamDto"}}}},"responses":{"200":{"description":"Messages spam status updated successfully","content":{"application/json":{"schema":{"properties":{"updatedCount":{"type":"number","example":5}}}}}},"400":{"description":"Bad Request - Validation failed or too many message IDs"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Bulk mark or unmark messages as spam","tags":["Messages"]}},"/v1/messages/{id}":{"get":{"description":"Get message by ID. Only returns message if it belongs to a recipient in a channel owned by the authenticated user.","operationId":"MessagesController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":395344,"type":"number"}}],"responses":{"200":{"description":"Message retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Message not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single message","tags":["Messages"]},"put":{"description":"Update message details. Only updates messages from recipients in channels owned by the authenticated user. All fields are optional. Can only update messages that have not been sent yet (dtsr = 0).","operationId":"MessagesController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":395344,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMessageDto"}}}},"responses":{"200":{"description":"Message updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Message does not belong to user or has already been sent"},"404":{"description":"Message not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing message","tags":["Messages"]},"delete":{"description":"Delete a message by ID. Only deletes messages from recipients in channels owned by the authenticated user. Can only delete messages that have not been sent yet (dtsr = 0). This is a hard delete - the message is permanently removed from the database.","operationId":"MessagesController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":395344,"type":"number"}}],"responses":{"204":{"description":"Message deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Message does not belong to user or has already been sent"},"404":{"description":"Message not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a message","tags":["Messages"]}},"/v1/messages/{id}/spam":{"put":{"description":"Toggle the spam status of a single message. Only updates messages from recipients in channels owned by the authenticated user.","operationId":"MessagesController_toggleSpam","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":395344,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkSpamDto"}}}},"responses":{"200":{"description":"Message spam status updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Message not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Mark or unmark a message as spam","tags":["Messages"]}},"/v1/messages/{id}/create-ticket":{"post":{"description":"Convert an inbox message into a support ticket. The message content becomes the first ticket message, and the contact information is used for the ticket. Optionally assign the ticket to a team member and set priority.","operationId":"MessagesController_createTicketFromMessage","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":395344,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketFromMessageDto"}}}},"responses":{"201":{"description":"Ticket created successfully from message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketFromMessageResponseDto"}}}},"400":{"description":"Bad Request - Message already converted to ticket"},"401":{"description":"Unauthorized - Invalid API Key or Token"},"404":{"description":"Message not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a support ticket from an inbox message","tags":["Messages"]}},"/v1/messages/{id}/reactions":{"get":{"description":"Get all messages that were sent as a reaction/reply to the specified message. Reactions are identified by matching the refid field to the original message wamid.","operationId":"MessagesController_findReactions","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":395344,"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"recipientId","required":false,"in":"query","description":"Filter by recipient ID","schema":{"example":81857,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":505,"type":"number"}},{"name":"direction","required":false,"in":"query","description":"Filter by message direction (s=sent, r=received)","schema":{"example":"r","type":"string","enum":["s","r"]}},{"name":"messageType","required":false,"in":"query","description":"Filter by message type","schema":{"example":"text","type":"string","enum":["text","image","video","audio","document","location","contact","sticker"]}},{"name":"search","required":false,"in":"query","description":"Search in message content","schema":{"example":"hello","type":"string"}},{"name":"spam","required":false,"in":"query","description":"Filter by spam status. true = only spam, false = exclude spam, undefined = all messages","schema":{"example":false,"type":"boolean"}},{"name":"reactionType","required":false,"in":"query","description":"Filter reactions by type. emoji=emoji reactions, button=button replies, text=text replies, all/omit=no filter","schema":{"example":"emoji","type":"string","enum":["all","emoji","button","text"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/MessageResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Message not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get reactions (reply messages) to a message","tags":["Messages"]}},"/v1/broadcasts":{"post":{"description":"Create a new broadcast message with optional media attachment. The broadcast is written to the database and will be picked up by the Transmitter worker for sending. Only creates broadcasts for channels owned by the authenticated user. Supports multipart/form-data for media upload.","operationId":"BroadcastsController_create","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateBroadcastDto"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateBroadcastDto"}}}},"responses":{"201":{"description":"Broadcast created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Channel does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new broadcast","tags":["Broadcasts"]},"get":{"description":"Get all broadcasts with pagination and optional filters. Only returns broadcasts from channels owned by the authenticated user.","operationId":"BroadcastsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":664,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by one or more channel IDs (comma-separated string or array). When set, takes precedence over \"channelId\". Returns broadcasts belonging to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"sendStatus","required":false,"in":"query","description":"Filter by send status","schema":{"$ref":"#/components/schemas/BroadcastSendStatus"}},{"name":"sendStatuses","required":false,"in":"query","description":"Filter by one or more send statuses (comma-separated string or array). When set, takes precedence over \"sendStatus\". Returns broadcasts matching any of the listed statuses.","schema":{"example":"sent,scheduled","type":"string"}},{"name":"segmentIds","required":false,"in":"query","description":"Filter by one or more segment IDs (comma-separated string or array). Use 0 to include broadcasts with no segment. Returns broadcasts matching any of the listed segments.","schema":{"example":"0,42","type":"string"}},{"name":"broadcastType","required":false,"in":"query","description":"Filter by broadcast type","schema":{"example":"text","type":"string","enum":["text","image","video","audio","document"]}},{"name":"isTest","required":false,"in":"query","description":"Filter by test broadcasts (1=only test, 0=exclude test)","schema":{"example":0,"type":"number","enum":[0,1]}},{"name":"search","required":false,"in":"query","description":"Search in broadcast message content","schema":{"example":"update","type":"string"}},{"name":"templateId","required":false,"in":"query","description":"Filter by template ID used by the broadcast","schema":{"example":486,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Field used to sort broadcasts","schema":{"default":"createdAt","type":"string","enum":["createdAt","scheduledAt"]}},{"name":"sortOrder","required":false,"in":"query","description":"Broadcast sort direction","schema":{"default":"desc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BroadcastResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all broadcasts","tags":["Broadcasts"]}},"/v1/broadcasts/{id}":{"get":{"description":"Get broadcast by ID. Only returns broadcast if it belongs to a channel owned by the authenticated user.","operationId":"BroadcastsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Broadcast ID","schema":{"example":31670,"type":"number"}}],"responses":{"200":{"description":"Broadcast retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Broadcast not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single broadcast","tags":["Broadcasts"]},"put":{"description":"Update broadcast details. Only updates broadcasts from channels owned by the authenticated user. All fields are optional. Can only update broadcasts that have not been sent yet (dtsnd = 0).","operationId":"BroadcastsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Broadcast ID","schema":{"example":31670,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBroadcastDto"}}}},"responses":{"200":{"description":"Broadcast updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Broadcast does not belong to user or is already sent"},"404":{"description":"Broadcast not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing broadcast","tags":["Broadcasts"]},"delete":{"description":"Delete a broadcast by ID. Only deletes broadcasts from channels owned by the authenticated user. Can only delete broadcasts that have not been sent yet (dtsnd = 0). This is a hard delete - the broadcast is permanently removed from the database.","operationId":"BroadcastsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Broadcast ID","schema":{"example":31670,"type":"number"}}],"responses":{"204":{"description":"Broadcast deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Broadcast does not belong to user or is already sent"},"404":{"description":"Broadcast not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a broadcast","tags":["Broadcasts"]}},"/v1/broadcasts/{id}/send":{"post":{"description":"Send an existing broadcast immediately. Changes the send status to pending and marks it for immediate sending by the Transmitter worker. Only sends broadcasts from channels owned by the authenticated user.","operationId":"BroadcastsController_send","parameters":[{"name":"id","required":true,"in":"path","description":"Broadcast ID","schema":{"example":31670,"type":"number"}}],"responses":{"200":{"description":"Broadcast queued for sending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Broadcast does not belong to user"},"404":{"description":"Broadcast not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Send a broadcast immediately","tags":["Broadcasts"]}},"/v1/tags":{"post":{"description":"Create a new tag for recipient categorization. The tag belongs to the authenticated user and can be assigned to multiple recipients.","operationId":"TagsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTagDto"}}}},"responses":{"201":{"description":"Tag created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new tag","tags":["Tags"]},"get":{"description":"Get all tags with pagination and optional filters. Only returns tags owned by the authenticated user. Excludes soft-deleted tags.","operationId":"TagsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in tag name or description","schema":{"example":"VIP","type":"string"}},{"name":"color","required":false,"in":"query","description":"Filter by tag color (hex format)","schema":{"example":"#3B82F6","type":"string"}}],"responses":{"200":{"description":"Tags retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/TagResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all tags","tags":["Tags"]}},"/v1/tags/export/download":{"get":{"description":"Export all tags to CSV or JSON format. The file is downloaded directly.","operationId":"TagsController_exportTags","parameters":[{"name":"format","required":false,"in":"query","description":"Export format (csv or json)","schema":{"enum":["csv","json"],"type":"string"}}],"responses":{"200":{"description":"Tags exported successfully"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Export all tags","tags":["Tags"]}},"/v1/tags/{id}":{"get":{"description":"Get tag by ID. Only returns tag if it belongs to the authenticated user.","operationId":"TagsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}}],"responses":{"200":{"description":"Tag retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single tag","tags":["Tags"]},"put":{"description":"Update tag details. Only updates tags owned by the authenticated user. All fields are optional.","operationId":"TagsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTagDto"}}}},"responses":{"200":{"description":"Tag updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Tag does not belong to user"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing tag","tags":["Tags"]},"delete":{"description":"Delete a tag by ID. Only deletes tags owned by the authenticated user. The tag and all tag assignments are permanently removed.","operationId":"TagsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}}],"responses":{"204":{"description":"Tag deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Tag does not belong to user"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a tag","tags":["Tags"]}},"/v1/tags/{id}/segments":{"get":{"description":"Returns all segments that have this tag assigned, paginated.","operationId":"TagsController_findTagSegments","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"example":20,"type":"number"}}],"responses":{"200":{"description":"Segments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TagSegmentItemDto"}},"total":{"type":"number"}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List segments using this tag","tags":["Tags"]}},"/v1/tags/{id}/bots":{"get":{"description":"Returns all bots that have this tag assigned, paginated.","operationId":"TagsController_findTagBots","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"example":20,"type":"number"}}],"responses":{"200":{"description":"Bots retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TagBotItemDto"}},"total":{"type":"number"}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List bots using this tag","tags":["Tags"]}},"/v1/tags/{id}/recipients":{"post":{"description":"Bulk assign tag to multiple recipients. Only assigns tags owned by the authenticated user. Duplicate assignments are ignored.","operationId":"TagsController_assignToRecipients","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignTagsDto"}}}},"responses":{"200":{"description":"Tag assigned to recipients successfully","content":{"application/json":{"schema":{"type":"object","properties":{"assigned":{"type":"number","description":"Number of new assignments created","example":3},"skipped":{"type":"number","description":"Number of recipients that already had this tag","example":1}}}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Tag does not belong to user"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Assign tag to recipients","tags":["Tags"]},"delete":{"description":"Bulk remove tag from multiple recipients. Only removes tags owned by the authenticated user. Non-existing assignments are ignored.","operationId":"TagsController_removeFromRecipients","parameters":[{"name":"id","required":true,"in":"path","description":"Tag ID","schema":{"example":123,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagsRemoveTagsDto"}}}},"responses":{"200":{"description":"Tag removed from recipients successfully","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"number","description":"Number of assignments removed","example":2}}}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Tag does not belong to user"},"404":{"description":"Tag not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Remove tag from recipients","tags":["Tags"]}},"/v1/tags/import/validate":{"post":{"description":"Validate tag data before importing. Returns validation errors and duplicate count without creating any records.","operationId":"TagsController_validateImport","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagsValidateImportDto"}}}},"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateResultDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Validate tags before import","tags":["Tags"]}},"/v1/tags/import":{"post":{"description":"Import tags from JSON data. Validates each tag and creates valid ones. Returns summary with imported count, skipped duplicates, and errors.","operationId":"TagsController_importTags","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportTagsDto"}}}},"responses":{"200":{"description":"Import result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagsImportResultDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Import tags","tags":["Tags"]}},"/v1/templates":{"post":{"description":"Create a new message template for quick messaging and standardized responses with optional media attachment. Only creates templates for channels owned by the authenticated user. Supports multipart/form-data for media upload.","operationId":"TemplatesController_create","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateTemplateDto"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateDto"}}}},"responses":{"201":{"description":"Template created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Channel does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new template","tags":["Templates"]},"get":{"description":"Get all templates with pagination and optional filters. Only returns templates from channels owned by the authenticated user.","operationId":"TemplatesController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":123,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by one or more channel IDs (comma-separated string or array). When set, takes precedence over \"channelId\". Returns templates belonging to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by active status","schema":{"example":true,"type":"boolean"}},{"name":"type","required":false,"in":"query","description":"Filter by type","schema":{"example":"text","type":"string","enum":["text","image","video","document","audio","location","contact","interactive"]}},{"name":"types","required":false,"in":"query","description":"Filter by one or more types (comma-separated string or array). When set, takes precedence over \"type\". Returns templates matching any of the listed types.","schema":{"example":"text,image","type":"string"}},{"name":"whatsappStatuses","required":false,"in":"query","description":"Filter by one or more WhatsApp template statuses (comma-separated or array of integers). Returns templates matching any of the listed wab_template_sts values.","schema":{"example":"4,5","type":"string"}},{"name":"folderId","required":false,"in":"query","description":"Filter by folder ID","schema":{"example":1,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in template name or message","schema":{"example":"welcome","type":"string"}}],"responses":{"200":{"description":"Templates retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/TemplateResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all templates","tags":["Templates"]}},"/v1/templates/export/download":{"get":{"description":"Export templates to CSV or JSON format. Optionally filter by channel.","operationId":"TemplatesController_exportTemplates","parameters":[{"name":"format","required":false,"in":"query","description":"Export format (csv or json)","schema":{"enum":["csv","json"],"type":"string"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":123,"type":"number"}}],"responses":{"200":{"description":"Templates exported successfully"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Export templates","tags":["Templates"]}},"/v1/templates/{id}":{"get":{"description":"Get template by ID. Only returns template if it belongs to a channel owned by the authenticated user.","operationId":"TemplatesController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":486,"type":"number"}}],"responses":{"200":{"description":"Template retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Template not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single template","tags":["Templates"]},"put":{"description":"Update template details. Only updates templates from channels owned by the authenticated user. All fields are optional.","operationId":"TemplatesController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":486,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateDto"}}}},"responses":{"200":{"description":"Template updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Template does not belong to user"},"404":{"description":"Template not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing template","tags":["Templates"]},"delete":{"description":"Delete a template by ID. Only deletes templates from channels owned by the authenticated user. This is a hard delete - the template is permanently removed from the database. Templates with undeletable flag cannot be deleted.","operationId":"TemplatesController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":486,"type":"number"}}],"responses":{"204":{"description":"Template deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Template does not belong to user or is undeletable"},"404":{"description":"Template not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a template","tags":["Templates"]}},"/v1/templates/import/validate":{"post":{"description":"Validate template data before importing. Returns validation errors and duplicate count without creating any records.","operationId":"TemplatesController_validateImport","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplatesValidateImportDto"}}}},"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateResultDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Validate templates before import","tags":["Templates"]}},"/v1/templates/import":{"post":{"description":"Import templates into a specific channel. Validates each template and creates valid ones. Returns summary with imported count, skipped duplicates, and errors.","operationId":"TemplatesController_importTemplates","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportTemplatesDto"}}}},"responses":{"200":{"description":"Import result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplatesImportResultDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Import templates","tags":["Templates"]}},"/v1/qr-codes":{"get":{"description":"Retrieve all QR codes for the authenticated user with pagination and optional filters.","operationId":"V1QrCodesController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":123,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by active status","schema":{"example":true,"type":"boolean"}},{"name":"folderId","required":false,"in":"query","description":"Filter by folder ID","schema":{"example":1,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in QR code name or keyword","schema":{"example":"event","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/QrCodeResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Invalid or missing API key"}},"security":[{"api-key":[]}],"summary":"List all QR codes","tags":["QR Codes"]},"post":{"description":"Generate a new QR code for channel registration and tracking.","operationId":"V1QrCodesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQrCodeDto"}}}},"responses":{"201":{"description":"QR code created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QrCodeResponseDto"}}}},"400":{"description":"Invalid input data"},"401":{"description":"Invalid or missing API key"},"403":{"description":"Channel not found or access denied"}},"security":[{"api-key":[]}],"summary":"Create a new QR code","tags":["QR Codes"]}},"/v1/qr-codes/{id}":{"get":{"description":"Retrieve detailed information about a specific QR code.","operationId":"V1QrCodesController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"QR Code ID","schema":{"type":"number"}}],"responses":{"200":{"description":"QR code retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QrCodeResponseDto"}}}},"401":{"description":"Invalid or missing API key"},"404":{"description":"QR code not found or does not belong to authenticated user"}},"security":[{"api-key":[]}],"summary":"Get QR code by ID","tags":["QR Codes"]},"put":{"description":"Update an existing QR code. All fields are optional.","operationId":"V1QrCodesController_update","parameters":[{"name":"id","required":true,"in":"path","description":"QR Code ID","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQrCodeDto"}}}},"responses":{"200":{"description":"QR code updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QrCodeResponseDto"}}}},"400":{"description":"Invalid input data"},"401":{"description":"Invalid or missing API key"},"404":{"description":"QR code not found or does not belong to authenticated user"}},"security":[{"api-key":[]}],"summary":"Update a QR code","tags":["QR Codes"]},"delete":{"description":"Delete a QR code by ID. This is a permanent deletion.","operationId":"V1QrCodesController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"QR Code ID","schema":{"type":"number"}}],"responses":{"204":{"description":"QR code deleted successfully"},"401":{"description":"Invalid or missing API key"},"404":{"description":"QR code not found or does not belong to authenticated user"}},"security":[{"api-key":[]}],"summary":"Delete a QR code","tags":["QR Codes"]}},"/v1/chats":{"get":{"operationId":"V1ChatsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by single channel ID. Kept for backwards compatibility; prefer \"channelIds\" for multi-select.","schema":{"example":5,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by one or more channel IDs (comma-separated string or array). When set, takes precedence over \"channelId\". Returns chats whose recipient belongs to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"unreadOnly","required":false,"in":"query","description":"Only show chats with unread messages","schema":{"example":true,"type":"boolean"}},{"name":"search","required":false,"in":"query","description":"Search in recipient name or phone number","schema":{"example":"John","type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by chat status","schema":{"example":"unread","type":"string","enum":["all","unread","read","archived"]}},{"name":"includeArchived","required":false,"in":"query","description":"Show archived chats","schema":{"default":false,"example":false,"type":"boolean"}}],"responses":{"200":{"description":"Chats retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ChatResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"List all chats","tags":["Chats"]}},"/v1/chats/{id}":{"get":{"operationId":"V1ChatsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Chat ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Chat retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Chat not found"}},"security":[{"api-key":[]}],"summary":"Get chat by ID","tags":["Chats"]}},"/v1/chats/{id}/messages":{"post":{"description":"Send a new message in this chat conversation via Public API. Creates a message record and queues it for delivery.","operationId":"V1ChatsController_sendMessage","parameters":[{"name":"id","required":true,"in":"path","description":"Chat ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageDto"}}}},"responses":{"201":{"description":"Message sent successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean"},"messageId":{"type":"number"}}}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Chat not found"}},"security":[{"api-key":[]}],"summary":"Send message in chat","tags":["Chats"]}},"/v1/bots":{"post":{"description":"Create a new automated bot with specified settings, trigger conditions, and actions. Required fields include name, channel ID, trigger type, and message template. Bot triggers can be based on keywords, schedules, events, or API calls. You can configure multi-step responses and actions like tagging recipients. Only creates bots for channels owned by the authenticated user.","operationId":"BotsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBotDto"}}}},"responses":{"201":{"description":"Bot created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Channel does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new bot","tags":["Bots"]},"get":{"description":"Retrieve a list of all bots configured in your account. Returns bot details including IDs, names, settings, trigger conditions, and action configurations. You can filter results by channel, active status, or search by name and content. Only returns bots from channels owned by the authenticated user.","operationId":"BotsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":5,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by one or more channel IDs (comma-separated string or array). When set, takes precedence over \"channelId\". Returns bots belonging to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by active status","schema":{"example":true,"type":"boolean"}},{"name":"type","required":false,"in":"query","description":"Filter by bot type","schema":{"example":"keyword","type":"string","enum":["keyword","schedule","event","ai"]}},{"name":"folderId","required":false,"in":"query","description":"Filter by folder ID","schema":{"example":1,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in bot name or message content","schema":{"example":"welcome","type":"string"}},{"name":"tagIds","required":false,"in":"query","description":"Filter by tag IDs (comma-separated or array). Returns bots that have at least one of the specified tags.","schema":{"example":"1,2,3","type":"string"}},{"name":"tagMatchMode","required":false,"in":"query","description":"How to match multiple tags: \"any\" = OR (at least one tag), \"all\" = AND (all tags required)","schema":{"default":"any","example":"any","type":"string","enum":["any","all"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BotResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all bots","tags":["Bots"]}},"/v1/bots/{id}":{"get":{"description":"Retrieve detailed information about a specific bot by its unique ID. Returns complete bot configuration including all trigger conditions (filters), content templates, action sequences, and performance statistics. This endpoint provides all available data needed to understand or replicate a bot's configuration. Only returns bot if it belongs to a channel owned by the authenticated user.","operationId":"BotsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Bot retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Bot not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single bot","tags":["Bots"]},"put":{"description":"Update an existing bot's configuration by ID. Modify trigger conditions, message content, action sequences, or scheduling parameters. Only the fields included in the request will be updated; all others remain unchanged. Status changes (enabling/disabling) can also be made with this endpoint. Only updates bots from channels owned by the authenticated user. All fields are optional.","operationId":"BotsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBotDto"}}}},"responses":{"200":{"description":"Bot updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"},"404":{"description":"Bot not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing bot","tags":["Bots"]},"delete":{"description":"Delete a bot by its unique ID. This permanently removes the bot from your account, including all its trigger conditions and action configurations. Note that match history data will be preserved in analytics even after deletion for reporting purposes. Only deletes bots from channels owned by the authenticated user. This is a hard delete with cascade to filters.","operationId":"BotsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Bot deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"},"404":{"description":"Bot not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a bot","tags":["Bots"]}},"/v1/bots/{id}/tags":{"post":{"description":"Assign an auto-tag to a bot. When recipients interact with this bot, they will automatically be assigned this tag. This is useful for segmentation and tracking which recipients have engaged with specific bots. Only assigns tags from the authenticated user to bots they own.","operationId":"BotsController_addTag","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTagDto"}}}},"responses":{"201":{"description":"Tag assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotTagAssignmentResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Bot or tag not found"},"409":{"description":"Tag already assigned to this bot"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Assign tag to bot","tags":["Bots"]},"get":{"description":"Retrieve all auto-tags assigned to a bot. These tags are automatically assigned to recipients when they interact with the bot. Returns tag details including names, colors, and assignment timestamps. Only returns tags for bots owned by the authenticated user.","operationId":"BotsController_getBotTags","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BotTagAssignmentResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Bot not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get bot auto-tags","tags":["Bots"]}},"/v1/bots/{id}/tags/{tagId}":{"delete":{"description":"Remove an auto-tag assignment from a bot. The bot will no longer automatically assign this tag to recipients who interact with it. Existing tags already assigned to recipients will remain. Only removes tags from bots owned by the authenticated user.","operationId":"BotsController_removeTag","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}},{"name":"tagId","required":true,"in":"path","description":"Tag ID to remove","schema":{"example":123,"type":"number"}}],"responses":{"204":{"description":"Tag removed successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Bot, tag, or assignment not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Remove tag from bot","tags":["Bots"]}},"/v1/bots/{id}/matches":{"get":{"description":"Retrieve the history of bot matches (trigger events). Shows when and how the bot was triggered, including the recipient, message, and trigger type (message-based or time-based). Supports pagination and search. Only returns matches for bots owned by the authenticated user.","operationId":"BotsController_getBotMatches","parameters":[{"name":"id","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number (1-based)","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":50,"example":50,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in message text","schema":{"example":"hello","type":"string"}},{"name":"eventTypes","required":false,"in":"query","description":"Filter by event types (comma-separated: message,time,unknown)","schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BotMatchResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Bot not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get bot match history","tags":["Bots"]}},"/v1/bots/{botId}/filters":{"post":{"description":"Create a new trigger condition filter for a specific bot. Filters define when a bot should be activated based on message content, recipient attributes, timing, or events. Supports various filter types (keyword, time, sender, etc.) and operators (equals, contains, regex, etc.). Only creates filters for bots owned by the authenticated user.","operationId":"BotFiltersController_create","parameters":[{"name":"botId","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBotFilterDto"}}}},"responses":{"201":{"description":"Filter created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotFilterResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new filter for bot","tags":["Bots"]},"get":{"description":"Retrieve all trigger condition filters for a specific bot. Returns filter details including name, description, type, operator, comparator, value, and performance statistics. Supports pagination and filtering by status, object type, or search text. Only returns filters for bots owned by the authenticated user.","operationId":"BotFiltersController_findAll","parameters":[{"name":"botId","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Status filter (0=inactive, 1=active)","schema":{"example":1,"type":"number"}},{"name":"objectType","required":false,"in":"query","description":"Object type filter","schema":{"$ref":"#/components/schemas/BotFilterObject"}},{"name":"search","required":false,"in":"query","description":"Search in name or description","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number (1-based)","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":20,"example":20,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BotFilterResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all filters for bot","tags":["Bots"]}},"/v1/bots/{botId}/filters/{filterId}":{"get":{"description":"Retrieve detailed information about a specific filter by its ID. Returns complete filter configuration including type, operator, value, and status. Only returns filter if it belongs to a bot owned by the authenticated user.","operationId":"BotFiltersController_findOne","parameters":[{"name":"botId","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}},{"name":"filterId","required":true,"in":"path","description":"Filter ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Filter retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotFilterResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"},"404":{"description":"Filter not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single filter","tags":["Bots"]},"put":{"description":"Update an existing filter's configuration by ID. Modify the filter type, operator, value, or status. Only updates filters for bots owned by the authenticated user. All fields are optional.","operationId":"BotFiltersController_update","parameters":[{"name":"botId","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}},{"name":"filterId","required":true,"in":"path","description":"Filter ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBotFilterDto"}}}},"responses":{"200":{"description":"Filter updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotFilterResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"},"404":{"description":"Filter not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing filter","tags":["Bots"]},"delete":{"description":"Remove a filter by its unique ID. This permanently deletes the filter from the bot. Only deletes filters for bots owned by the authenticated user. This is a hard delete.","operationId":"BotFiltersController_remove","parameters":[{"name":"botId","required":true,"in":"path","description":"Bot ID","schema":{"example":1,"type":"number"}},{"name":"filterId","required":true,"in":"path","description":"Filter ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Filter deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot does not belong to user"},"404":{"description":"Filter not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a filter","tags":["Bots"]}},"/v1/segments":{"post":{"description":"Create a new target group segmentation with specified attributes. Required fields include name and channel_id. Segmentations help organize recipients into groups based on tags and criteria for targeted messaging campaigns. Only creates segmentations for channels owned by the authenticated user.","operationId":"SegmentationsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSegmentationDto"}}}},"responses":{"201":{"description":"Segmentation created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentationResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Channel does not belong to user"}},"security":[{"api-key":[]}],"summary":"Create a new segmentation","tags":["Segments"]},"get":{"description":"Retrieve a list of all segmentations in your account. Returns segmentation details including IDs, names, descriptions, recipient counts, and associated tags. Only returns segmentations from channels owned by the authenticated user.","operationId":"SegmentationsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":5,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by multiple channel IDs (comma-separated or array). Takes precedence over channelId. Returns segmentations belonging to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"optInOut","required":false,"in":"query","description":"Filter by opt-in/out enabled status. \"enabled\" = optio_sts=1, \"disabled\" = optio_sts=0.","schema":{"example":"enabled","type":"string","enum":["enabled","disabled"]}},{"name":"search","required":false,"in":"query","description":"Search in segmentation name or description","schema":{"example":"vip","type":"string"}},{"name":"tagIds","required":false,"in":"query","description":"Filter by tag IDs (comma-separated or array). Returns segmentations that have at least one of the specified tags.","schema":{"example":"1,2,3","type":"string"}},{"name":"tagMatchMode","required":false,"in":"query","description":"How to match multiple tags: \"any\" = OR (at least one tag), \"all\" = AND (all tags required)","schema":{"default":"any","example":"any","type":"string","enum":["any","all"]}}],"responses":{"200":{"description":"Segmentations retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/SegmentationResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"List all segmentations","tags":["Segments"]}},"/v1/segments/{id}":{"get":{"description":"Retrieve detailed information about a specific segmentation by its unique ID. Returns complete segmentation configuration including criteria, opt-in/out settings, and statistics. Only returns segmentation if it belongs to a channel owned by the authenticated user.","operationId":"SegmentationsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Segmentation ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Segmentation retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentationResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Segmentation not found"}},"security":[{"api-key":[]}],"summary":"Get single segmentation","tags":["Segments"]},"put":{"description":"Update an existing segmentation by ID. Modify the name, description, color, or tag criteria. The response returns the updated segmentation. Only updates segmentations from channels owned by the authenticated user. All fields are optional.","operationId":"SegmentationsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Segmentation ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSegmentationDto"}}}},"responses":{"200":{"description":"Segmentation updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentationResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Segmentation does not belong to user"},"404":{"description":"Segmentation not found"}},"security":[{"api-key":[]}],"summary":"Update an existing segmentation","tags":["Segments"]},"delete":{"description":"Remove a segmentation by its unique ID. This permanently deletes the segmentation from your account. Only deletes segmentations from channels owned by the authenticated user. This is a hard delete.","operationId":"SegmentationsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Segmentation ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Segmentation deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Segmentation does not belong to user"},"404":{"description":"Segmentation not found"}},"security":[{"api-key":[]}],"summary":"Delete a segmentation","tags":["Segments"]}},"/v1/segments/{id}/tags":{"post":{"description":"Assign a tag filter to a segmentation. Recipients must have this tag to be included in the segmentation. Multiple tags can be assigned to create complex filtering criteria. Only assigns tags from the authenticated user to segmentations they own.","operationId":"SegmentationsController_addTag","parameters":[{"name":"id","required":true,"in":"path","description":"Segmentation ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTagDto"}}}},"responses":{"201":{"description":"Tag assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagAssignmentResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Segmentation or tag not found"},"409":{"description":"Tag already assigned to this segmentation"}},"security":[{"api-key":[]}],"summary":"Assign tag to segmentation","tags":["Segments"]},"get":{"description":"Retrieve all tag filters assigned to a segmentation. These tags determine which recipients are included in the segmentation. Returns tag details including names, colors, and assignment timestamps. Only returns tags for segmentations owned by the authenticated user.","operationId":"SegmentationsController_getSegmentationTags","parameters":[{"name":"id","required":true,"in":"path","description":"Segmentation ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Segmentation tags retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Segmentation not found"}},"security":[{"api-key":[]}],"summary":"Get segmentation tag filters","tags":["Segments"]}},"/v1/segments/{id}/tags/{tagId}":{"delete":{"description":"Remove a tag filter from a segmentation. Recipients with this tag will no longer be included in the segmentation unless other tag filters still match. Only removes tags from segmentations owned by the authenticated user.","operationId":"SegmentationsController_removeTag","parameters":[{"name":"id","required":true,"in":"path","description":"Segmentation ID","schema":{"example":1,"type":"number"}},{"name":"tagId","required":true,"in":"path","description":"Tag ID to remove","schema":{"example":123,"type":"number"}}],"responses":{"204":{"description":"Tag removed successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Segmentation, tag, or assignment not found"}},"security":[{"api-key":[]}],"summary":"Remove tag from segmentation","tags":["Segments"]}},"/v1/short-links":{"get":{"operationId":"V1ShortLinksController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in original URL","schema":{"example":"example.com","type":"string"}}],"responses":{"200":{"description":"Short links retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ShortLinkResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"List all short links","tags":["Short Links"]},"post":{"operationId":"V1ShortLinksController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShortLinkDto"}}}},"responses":{"201":{"description":"Short link created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLinkResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"Create a new short link","tags":["Short Links"]}},"/v1/short-links/{id}":{"get":{"operationId":"V1ShortLinksController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Short link ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Short link retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLinkResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Short link not found"}},"security":[{"api-key":[]}],"summary":"Get short link by ID","tags":["Short Links"]},"put":{"operationId":"V1ShortLinksController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Short link ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateShortLinkDto"}}}},"responses":{"200":{"description":"Short link updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLinkResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Short link not found"}},"security":[{"api-key":[]}],"summary":"Update a short link","tags":["Short Links"]},"delete":{"operationId":"V1ShortLinksController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Short link ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Short link deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Short link not found"}},"security":[{"api-key":[]}],"summary":"Delete a short link","tags":["Short Links"]}},"/v1/feeds":{"get":{"operationId":"V1FeedsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":1,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by active status","schema":{"example":true,"type":"boolean"}},{"name":"search","required":false,"in":"query","description":"Search in name, description, or URL","schema":{"example":"tech","type":"string"}}],"responses":{"200":{"description":"Feeds retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/FeedResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"List all content feeds","tags":["Feeds"]},"post":{"operationId":"V1FeedsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedDto"}}}},"responses":{"201":{"description":"Feed created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"Create a new content feed","tags":["Feeds"]}},"/v1/feeds/{id}":{"get":{"operationId":"V1FeedsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Feed ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Feed retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Feed not found"}},"security":[{"api-key":[]}],"summary":"Get feed by ID","tags":["Feeds"]},"put":{"operationId":"V1FeedsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Feed ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFeedDto"}}}},"responses":{"200":{"description":"Feed updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Feed not found"}},"security":[{"api-key":[]}],"summary":"Update a content feed","tags":["Feeds"]},"delete":{"operationId":"V1FeedsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Feed ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Feed deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Feed not found"}},"security":[{"api-key":[]}],"summary":"Delete a content feed","tags":["Feeds"]}},"/v1/polls":{"get":{"operationId":"V1PollsController_findAll","parameters":[],"responses":{"200":{"description":"Polls retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"List all polls","tags":["Polls"]},"post":{"operationId":"V1PollsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePollDto"}}}},"responses":{"201":{"description":"Poll created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"api-key":[]}],"summary":"Create a new poll","tags":["Polls"]}},"/v1/polls/{id}":{"get":{"operationId":"V1PollsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Poll ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Poll retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Poll not found"}},"security":[{"api-key":[]}],"summary":"Get poll by ID","tags":["Polls"]},"put":{"operationId":"V1PollsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Poll ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePollDto"}}}},"responses":{"200":{"description":"Poll updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Poll not found"}},"security":[{"api-key":[]}],"summary":"Update a poll","tags":["Polls"]},"delete":{"operationId":"V1PollsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Poll ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Poll deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Poll not found"}},"security":[{"api-key":[]}],"summary":"Delete a poll","tags":["Polls"]}},"/v1/channels/{channelId}/tickets":{"post":{"description":"Create a new support ticket for customer inquiries and issues. Tickets provide structured customer support management. \\n\\nUse cases:\\n- **Customer support**: Handle customer questions and issues\\n- **Bug reports**: Track and manage bug reports\\n- **Feature requests**: Collect and manage feature requests\\n- **General inquiries**: Manage any customer communication\\n\\n\\nAfter creating a ticket, you can add messages using the ticket messages endpoints to track the conversation.","operationId":"TicketsController_create","parameters":[{"name":"channelId","required":true,"in":"path","description":"Channel ID","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketDto"}}}},"responses":{"201":{"description":"Ticket created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketResponseDto"}}}},"400":{"description":"Invalid request data"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Channel not found or access denied"}},"security":[{"api-key":[]}],"summary":"Create a new ticket","tags":["Tickets"]},"get":{"description":"Retrieve tickets for a specific channel (paginated). This includes tickets in all states (new, open, closed). \\n\\nUse this endpoint to:\\n- Review all support tickets\\n- Monitor ticket status and priority\\n- Filter tickets by status or priority (client-side)\\n- Export ticket data for reporting\\n\\n\\nUse limit/offset query parameters to paginate. Defaults: limit=500, offset=0. Hard cap: 1000.","operationId":"TicketsController_findAll","parameters":[{"name":"channelId","required":true,"in":"path","description":"Channel ID","schema":{"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of tickets to skip (default 0)","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of tickets to return (1-1000, default 500)","schema":{"type":"number"}}],"responses":{"200":{"description":"Tickets retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketResponseDto"}}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Channel not found or access denied"}},"security":[{"api-key":[]}],"summary":"List all tickets","tags":["Tickets"]}},"/v1/channels/{channelId}/tickets/{id}":{"get":{"description":"Retrieve detailed information about a specific ticket including customer details and status. \\n\\nReturns:\\n- Ticket ID and reference number\\n- Customer information (name, email, company)\\n- Subject and priority\\n- Status and assigned user\\n- Timestamps (created, updated, closed)","operationId":"TicketsController_findOne","parameters":[{"name":"channelId","required":true,"in":"path","description":"Channel ID","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Ticket found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketResponseDto"}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Channel not found or access denied"},"404":{"description":"Ticket not found"}},"security":[{"api-key":[]}],"summary":"Get specific ticket","tags":["Tickets"]},"put":{"description":"Modify an existing ticket. You can update customer information, status, priority, and other ticket details. \\n\\nCommon use cases:\\n- **Update status**: Change from new to open or closed\\n- **Set priority**: Mark tickets as urgent or adjust priority\\n- **Update customer info**: Correct customer details\\n- **Assign ticket**: Set assigned user ID\\n\\n\\nImportant: Setting status=3 (closed) automatically records the close timestamp.","operationId":"TicketsController_update","parameters":[{"name":"channelId","required":true,"in":"path","description":"Channel ID","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketDto"}}}},"responses":{"200":{"description":"Ticket updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketResponseDto"}}}},"400":{"description":"Invalid request data"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Channel not found or access denied"},"404":{"description":"Ticket not found"}},"security":[{"api-key":[]}],"summary":"Update ticket","tags":["Tickets"]},"delete":{"description":"Archive a ticket without deleting its support history or associated messages. \\n\\nBefore archiving:\\n- Export ticket data if you need to keep records\\n- Verify the ticket is no longer needed\\n- Consider closing (status=3) instead of archiving\\n\\n\\nAfter archiving:\\n- The ticket is hidden from default lists and sync responses\\n- Ticket messages remain retained for the support record","operationId":"TicketsController_remove","parameters":[{"name":"channelId","required":true,"in":"path","description":"Channel ID","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Ticket archived successfully"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Channel not found or access denied"},"404":{"description":"Ticket not found"}},"security":[{"api-key":[]}],"summary":"Archive ticket","tags":["Tickets"]}},"/v1/tickets":{"get":{"description":"Retrieve all tickets across all channels for the authenticated user. This includes tickets in all states (new, open, closed). \\n\\nSupports pagination and filtering:\\n- **page**: Page number (default: 1)\\n- **limit**: Items per page (default: 20)\\n- **search**: Search in subject field\\n- **channelId**: Filter by specific channel\\n- **status**: Filter by status (new/open/closed)\\n- **priority**: Filter by priority (low/normal/high/urgent)\\n\\n\\nUse this endpoint to:\\n- Review all support tickets across channels\\n- Monitor ticket status and priority\\n- Search and filter tickets\\n- Export ticket data for reporting","operationId":"PublicTicketsController_findAll","parameters":[{"name":"priority","required":false,"in":"query","description":"Filter by priority (low/normal/high/urgent)","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by status (new/open/closed)","schema":{"type":"string"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in subject field","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page (default: 20)","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number (default: 1)","schema":{"type":"number"}}],"responses":{"200":{"description":"Tickets retrieved successfully"},"401":{"description":"Unauthorized - Invalid or missing API key"}},"security":[{"api-key":[]}],"summary":"List all tickets","tags":["Tickets"]}},"/v1/tickets/{id}":{"get":{"description":"Retrieve detailed information about a specific ticket including customer details and status. \\n\\nReturns:\\n- Ticket ID and reference number\\n- Customer information (name, email, company)\\n- Subject and priority\\n- Status and assigned user\\n- Chat window status (for messaging platforms)\\n- Timestamps (created, updated, closed)","operationId":"PublicTicketsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Ticket retrieved successfully"},"401":{"description":"Unauthorized - Invalid or missing API key"},"404":{"description":"Ticket not found"}},"security":[{"api-key":[]}],"summary":"Get ticket by ID","tags":["Tickets"]}},"/v1/tickets/{ticketId}/messages":{"post":{"description":"Add a new message/comment to an existing ticket. Messages track the conversation between support and customers. \\n\\nUse cases:\\n- **Support responses**: Send responses to customer inquiries\\n- **Internal notes**: Add internal comments (visible only to support)\\n- **Status updates**: Document ticket progress\\n- **Resolution details**: Record how issue was resolved\\n\\n\\nImportant notes:\\n- Messages are marked as outgoing (from support)\\n- Adding a message updates the ticket last-modified timestamp\\n- Messages are ordered chronologically","operationId":"TicketMessagesController_create","parameters":[{"name":"ticketId","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketMessageDto"}}}},"responses":{"201":{"description":"Message added successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessageResponseDto"}}}},"400":{"description":"Invalid request data"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Ticket not found or access denied"}},"security":[{"api-key":[]}],"summary":"Add message to ticket","tags":["Tickets"]},"get":{"description":"Retrieve all messages for a specific ticket, ordered chronologically (oldest first). \\n\\nUse this endpoint to:\\n- Display full ticket conversation\\n- Review support interaction history\\n- Export conversation for records\\n- Analyze response times","operationId":"TicketMessagesController_findAll","parameters":[{"name":"ticketId","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Messages retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketMessageResponseDto"}}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Ticket not found or access denied"}},"security":[{"api-key":[]}],"summary":"List all ticket messages","tags":["Tickets"]}},"/v1/tickets/{ticketId}/messages/{id}":{"get":{"description":"Retrieve detailed information about a specific message in a ticket. \\n\\nReturns:\\n- Message content\\n- Direction (in=from customer, out=from support)\\n- Author ID\\n- Timestamp","operationId":"TicketMessagesController_findOne","parameters":[{"name":"ticketId","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","description":"Ticket Message ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Message found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessageResponseDto"}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Ticket not found or access denied"},"404":{"description":"Message not found"}},"security":[{"api-key":[]}],"summary":"Get specific ticket message","tags":["Tickets"]},"delete":{"description":"Permanently delete a message from a ticket. This action is irreversible. \\n\\nBefore deleting:\\n- Verify the message should be removed\\n- Consider that this may break conversation flow\\n- Export message content if needed for records\\n\\n\\nAfter deletion:\\n- Message is permanently removed from ticket\\n- No recovery is possible - deletion is permanent","operationId":"TicketMessagesController_remove","parameters":[{"name":"ticketId","required":true,"in":"path","description":"Ticket ID","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","description":"Ticket Message ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Message deleted successfully"},"401":{"description":"Unauthorized - Invalid or missing API key"},"403":{"description":"Forbidden - Ticket not found or access denied"},"404":{"description":"Message not found"}},"security":[{"api-key":[]}],"summary":"Remove ticket message","tags":["Tickets"]}},"/v1/tickets/{ticketId}/reply":{"post":{"description":"Sends a reply through the legacy ticket-reply path so the customer actually receives the email and the message appears in both the ticket history and the Nachrichtenprotokoll.\n\n**Body must be raw text only.** Do NOT add a salutation or sign-off: for email-channel tickets the legacy `tickets_email()` path automatically prepends the personalised salutation (from `tickets.title`) and appends the localised footer (`lcl_mail_footer_salutation`). Sending your own greetings produces duplicated headers/footers in the delivered email. See `.claude/docs/email-system.md` (Auto-Wrapping von Customer-Replies).","operationId":"PublicTicketReplyController_reply","parameters":[{"name":"ticketId","required":true,"in":"path","description":"Database id of the ticket (`tickets.id`)","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplyTicketDto"}}}},"responses":{"201":{"description":"Reply has been sent and recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessageResponseDto"}}}},"400":{"description":"Empty or invalid reply payload"},"401":{"description":"Not authenticated"},"404":{"description":"Ticket not found or not accessible"}},"security":[{"api-key":[]}],"summary":"Reply to a ticket as support agent","tags":["Tickets"]}},"/v1/super-widgets":{"post":{"description":"Create a SuperWidget that combines multiple widgets. Users can select which channel to subscribe to from a single interface.","operationId":"SuperWidgetsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSuperWidgetDto"}}}},"responses":{"201":{"description":"SuperWidget created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperWidgetResponseDto"}}}}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create SuperWidget","tags":["Super Widgets"]},"get":{"description":"Get all SuperWidgets","operationId":"SuperWidgetsController_findAll","parameters":[{"name":"search","required":false,"in":"query","description":"Search by name","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponseDto"}}}}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List SuperWidgets","tags":["Super Widgets"]}},"/v1/super-widgets/{id}":{"get":{"description":"Get SuperWidget details including linked widgets","operationId":"SuperWidgetsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Super Widget ID","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperWidgetResponseDto"}}}}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get SuperWidget","tags":["Super Widgets"]},"put":{"description":"Update SuperWidget configuration and linked widgets","operationId":"SuperWidgetsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Super Widget ID","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSuperWidgetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperWidgetResponseDto"}}}}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update SuperWidget","tags":["Super Widgets"]},"delete":{"operationId":"SuperWidgetsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Super Widget ID","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete SuperWidget","tags":["Super Widgets"]}},"/v1/flows":{"post":{"description":"Create a new flow for orchestrating multiple bots in a visual workflow. A flow belongs to a specific channel and can contain multiple bot nodes connected by edges.","operationId":"FlowsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFlowDto"}}}},"responses":{"201":{"description":"Flow created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Channel does not belong to user"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new flow","tags":["Flows"]},"get":{"description":"Retrieve a list of all flows in your account. Returns flow details including IDs, names, descriptions, and associated channel. You can filter by channel, status, or search by name/description.","operationId":"FlowsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"channelId","required":false,"in":"query","description":"Filter by channel ID","schema":{"example":5,"type":"number"}},{"name":"channelIds","required":false,"in":"query","description":"Filter by one or more channel IDs (comma-separated string or array). When set, takes precedence over \"channelId\". Returns flows belonging to any of the listed channels.","schema":{"example":"1,2,3","type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by active status","schema":{"example":true,"type":"boolean"}},{"name":"folderId","required":false,"in":"query","description":"Filter by folder ID","schema":{"example":1,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in flow name or description","schema":{"example":"welcome","type":"string"}}],"responses":{"200":{"description":"Flows retrieved successfully","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/FlowResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all flows","tags":["Flows"]}},"/v1/flows/{id}":{"get":{"description":"Retrieve detailed information about a specific flow including all nodes (bot placements) and edges (connections between nodes).","operationId":"FlowsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Flow retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single flow","tags":["Flows"]},"put":{"description":"Update flow properties like name, description, color, or status. Only the fields included in the request will be updated.","operationId":"FlowsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlowDto"}}}},"responses":{"200":{"description":"Flow updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing flow","tags":["Flows"]},"delete":{"description":"Delete a flow and all its nodes and edges. This does not delete the bots referenced by the nodes.","operationId":"FlowsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Flow deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a flow","tags":["Flows"]}},"/v1/flows/{flowId}/nodes":{"post":{"description":"Add a bot as a node in the flow. The bot must belong to the same channel as the flow.","operationId":"FlowNodesController_create","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFlowNodeDto"}}}},"responses":{"201":{"description":"Node created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowNodeResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot not in same channel as flow"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Add a node to a flow","tags":["Flows"]},"get":{"description":"Retrieve all nodes (bot placements) in a specific flow.","operationId":"FlowNodesController_findAll","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Nodes retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlowNodeResponseDto"}}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all nodes in a flow","tags":["Flows"]}},"/v1/flows/{flowId}/nodes/{nodeId}":{"get":{"description":"Retrieve details of a specific node in a flow.","operationId":"FlowNodesController_findOne","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}},{"name":"nodeId","required":true,"in":"path","description":"Node ID","schema":{"example":5,"type":"number"}}],"responses":{"200":{"description":"Node retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowNodeResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow or node not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get a single node","tags":["Flows"]},"put":{"description":"Update node position, type, or associated bot. If changing the bot, it must belong to the same channel as the flow.","operationId":"FlowNodesController_update","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}},{"name":"nodeId","required":true,"in":"path","description":"Node ID","schema":{"example":5,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlowNodeDto"}}}},"responses":{"200":{"description":"Node updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowNodeResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"403":{"description":"Forbidden - Bot not in same channel as flow"},"404":{"description":"Flow or node not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update a node","tags":["Flows"]},"delete":{"description":"Remove a node from the flow. This also removes all edges connected to this node. The underlying bot is not deleted.","operationId":"FlowNodesController_remove","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}},{"name":"nodeId","required":true,"in":"path","description":"Node ID","schema":{"example":5,"type":"number"}}],"responses":{"204":{"description":"Node deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow or node not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Remove a node from a flow","tags":["Flows"]}},"/v1/flows/{flowId}/edges":{"post":{"description":"Create a connection between two nodes in a flow. Both nodes must exist in the same flow.","operationId":"FlowEdgesController_create","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFlowEdgeDto"}}}},"responses":{"201":{"description":"Edge created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEdgeResponseDto"}}}},"400":{"description":"Bad Request - Invalid node IDs or self-referencing edge"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create an edge between nodes","tags":["Flows"]},"get":{"description":"Retrieve all edges (connections between nodes) in a specific flow.","operationId":"FlowEdgesController_findAll","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"Edges retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlowEdgeResponseDto"}}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all edges in a flow","tags":["Flows"]}},"/v1/flows/{flowId}/edges/{edgeId}":{"get":{"description":"Retrieve details of a specific edge in a flow.","operationId":"FlowEdgesController_findOne","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}},{"name":"edgeId","required":true,"in":"path","description":"Edge ID","schema":{"example":5,"type":"number"}}],"responses":{"200":{"description":"Edge retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEdgeResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow or edge not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get a single edge","tags":["Flows"]},"put":{"description":"Update edge properties like source/target nodes, label, or type.","operationId":"FlowEdgesController_update","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}},{"name":"edgeId","required":true,"in":"path","description":"Edge ID","schema":{"example":5,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlowEdgeDto"}}}},"responses":{"200":{"description":"Edge updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEdgeResponseDto"}}}},"400":{"description":"Bad Request - Invalid node IDs or self-referencing edge"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow or edge not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an edge","tags":["Flows"]},"delete":{"description":"Remove a connection between nodes in a flow.","operationId":"FlowEdgesController_remove","parameters":[{"name":"flowId","required":true,"in":"path","description":"Flow ID","schema":{"example":1,"type":"number"}},{"name":"edgeId","required":true,"in":"path","description":"Edge ID","schema":{"example":5,"type":"number"}}],"responses":{"204":{"description":"Edge deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key"},"404":{"description":"Flow or edge not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete an edge","tags":["Flows"]}},"/v1/bot-env-vars":{"post":{"description":"Create a new environment variable definition. The key must be unique per user, max 16 characters, and can only contain alphanumeric characters and underscores.","operationId":"BotEnvVarsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotEnvVarsCreateBotEnvVarDto"}}}},"responses":{"201":{"description":"Variable created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotEnvVarsBotEnvVarResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"409":{"description":"Variable with this key already exists"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Create a new bot environment variable","tags":["Bot Environment Variables"]},"get":{"description":"Get all environment variable definitions with pagination and optional filters. Only returns variables owned by the authenticated user.","operationId":"BotEnvVarsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in key or description","schema":{"example":"customer","type":"string"}},{"name":"color","required":false,"in":"query","description":"Filter by color (hex format)","schema":{"example":"#3B82F6","type":"string"}},{"name":"folderId","required":false,"in":"query","description":"Filter by object folder ID (0 means no folder)","schema":{"example":12,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BotEnvVarsBotEnvVarResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key or JWT"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"List all bot environment variables","tags":["Bot Environment Variables"]}},"/v1/bot-env-vars/{id}":{"get":{"description":"Get variable definition by ID. Only returns variable if it belongs to the authenticated user.","operationId":"BotEnvVarsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Variable ID","schema":{"example":123,"type":"number"}}],"responses":{"200":{"description":"Variable retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotEnvVarsBotEnvVarResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Variable not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get single bot environment variable","tags":["Bot Environment Variables"]},"put":{"description":"Update variable description or color. The key cannot be changed after creation. Only updates variables owned by the authenticated user.","operationId":"BotEnvVarsController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Variable ID","schema":{"example":123,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotEnvVarsUpdateBotEnvVarDto"}}}},"responses":{"200":{"description":"Variable updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotEnvVarsBotEnvVarResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Variable not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update an existing bot environment variable","tags":["Bot Environment Variables"]},"delete":{"description":"Delete a variable definition. This will fail if any bots are using this variable or if any recipients have values for it. Remove all usages first.","operationId":"BotEnvVarsController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Variable ID","schema":{"example":123,"type":"number"}}],"responses":{"204":{"description":"Variable deleted successfully"},"400":{"description":"Cannot delete - variable is in use by bots or has recipient values"},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Variable not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a bot environment variable","tags":["Bot Environment Variables"]}},"/v1/bot-env-vars/{id}/values":{"get":{"description":"Get all recipient-specific values for this variable with pagination. Includes recipient name and identifier.","operationId":"BotEnvVarsController_getValues","parameters":[{"name":"id","required":true,"in":"path","description":"Variable ID","schema":{"example":123,"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number (starts at 1)","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Search in recipient name or identifier","schema":{"example":"john","type":"string"}},{"name":"recipientId","required":false,"in":"query","description":"Filter by recipient ID","schema":{"example":789,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BotEnvVarValueResponseDto"}},"pagination":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":5}}},"timestamp":{"type":"string","example":"2025-01-01T00:00:00.000Z"}},"required":["success","data","pagination","timestamp"]}}}},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Variable not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get recipient values for a variable","tags":["Bot Environment Variables"]}},"/v1/bot-env-vars/{id}/bots":{"get":{"description":"Get all bots that are configured to set this environment variable. Shows the value each bot sets.","operationId":"BotEnvVarsController_getBots","parameters":[{"name":"id","required":true,"in":"path","description":"Variable ID","schema":{"example":123,"type":"number"}}],"responses":{"200":{"description":"Bots retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BotEnvVarBotUsageDto"}}}}},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Variable not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get bots using this variable","tags":["Bot Environment Variables"]}},"/v1/bot-env-vars/values/{valueId}":{"put":{"description":"Update the value or expiration for a specific recipient-variable assignment.","operationId":"BotEnvVarsController_updateValue","parameters":[{"name":"valueId","required":true,"in":"path","description":"Value ID","schema":{"example":456,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBotEnvValueDto"}}}},"responses":{"200":{"description":"Value updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BotEnvVarValueResponseDto"}}}},"400":{"description":"Bad Request - Validation failed"},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Value not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Update a recipient value","tags":["Bot Environment Variables"]},"delete":{"description":"Delete a specific recipient-variable value assignment.","operationId":"BotEnvVarsController_deleteValue","parameters":[{"name":"valueId","required":true,"in":"path","description":"Value ID","schema":{"example":456,"type":"number"}}],"responses":{"204":{"description":"Value deleted successfully"},"401":{"description":"Unauthorized - Invalid API Key or JWT"},"404":{"description":"Value not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a recipient value","tags":["Bot Environment Variables"]}},"/v1/contacts/{contactId}/custom-fields":{"get":{"description":"Get all custom field values for a specific contact. Returns all defined fields with their current values.","operationId":"CustomFieldValuesController_getContactCustomFields","parameters":[{"name":"contactId","required":true,"in":"path","description":"Contact/Recipient ID","schema":{"example":456,"type":"number"}}],"responses":{"200":{"description":"Custom field values retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CustomFieldValueResponseDto"}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Contact not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Get all custom field values for a contact","tags":["Custom Fields"]},"put":{"description":"Set or update multiple custom field values at once. Use field keys as property names.","operationId":"CustomFieldValuesController_setContactCustomFields","parameters":[{"name":"contactId","required":true,"in":"path","description":"Contact/Recipient ID","schema":{"example":456,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetCustomFieldValuesDto"},"examples":{"example1":{"summary":"Set multiple values","value":{"values":{"customer_id":"K-12345","birthday":"1990-05-15","vip_status":"true"}}}}}}},"responses":{"200":{"description":"Custom field values updated successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CustomFieldValueResponseDto"}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Contact not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Set multiple custom field values for a contact","tags":["Custom Fields"]}},"/v1/contacts/{contactId}/custom-fields/{fieldId}":{"put":{"description":"Set or update a single custom field value for a contact.","operationId":"CustomFieldValuesController_setContactCustomFieldValue","parameters":[{"name":"contactId","required":true,"in":"path","description":"Contact/Recipient ID","schema":{"example":456,"type":"number"}},{"name":"fieldId","required":true,"in":"path","description":"Custom field definition ID","schema":{"example":1,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"value":{"type":"string","example":"K-12345","description":"The value to set (use null to clear)"}}}}}},"responses":{"200":{"description":"Custom field value updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldValueResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Contact or field not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Set a single custom field value for a contact","tags":["Custom Fields"]},"delete":{"description":"Remove the value of a custom field for a specific contact.","operationId":"CustomFieldValuesController_deleteContactCustomFieldValue","parameters":[{"name":"contactId","required":true,"in":"path","description":"Contact/Recipient ID","schema":{"example":456,"type":"number"}},{"name":"fieldId","required":true,"in":"path","description":"Custom field definition ID","schema":{"example":1,"type":"number"}}],"responses":{"204":{"description":"Custom field value deleted successfully"},"401":{"description":"Unauthorized"},"404":{"description":"Contact or field not found"}},"security":[{"jwt":[]},{"api-key":[]}],"summary":"Delete a custom field value for a contact","tags":["Custom Fields"]}},"/v1/contacts/{contactId}/orders":{"get":{"operationId":"PublicContactOrdersController_findByContact","parameters":[{"name":"contactId","required":true,"in":"path","description":"Contact ID","schema":{"type":"number"}},{"name":"limit","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Orders retrieved successfully"},"404":{"description":"Contact not found"}},"security":[{"api-key":[]}],"summary":"Get orders for a contact","tags":["Contact Orders"]}},"/v1/contacts/{contactId}/orders/stats":{"get":{"operationId":"PublicContactOrdersController_getStats","parameters":[{"name":"contactId","required":true,"in":"path","description":"Contact ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Order statistics retrieved successfully"},"404":{"description":"Contact not found"}},"security":[{"api-key":[]}],"summary":"Get order statistics for a contact","tags":["Contact Orders"]}},"/":{"get":{"description":"Returns API metadata, available endpoints, and documentation links","operationId":"AppController_getApiInfo","parameters":[],"responses":{"200":{"description":"API information retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"instantKOM REST API"},"description":{"type":"string","example":"Multi-Channel Messaging Platform API"},"version":{"type":"string","example":"3.95.2"},"status":{"type":"string","example":"operational"},"environment":{"type":"string","example":"development"},"documentation":{"type":"object","properties":{"catalog":{"type":"string"},"swagger":{"type":"string"},"openapi":{"type":"string"}}},"endpoints":{"type":"object","properties":{"health":{"type":"string"}}},"links":{"type":"object","properties":{"homepage":{"type":"string"},"support":{"type":"string"}}}}}}}}},"security":[{}],"summary":"Get API information","tags":["API Info"]}}},"info":{"title":"instantKOM Public API","description":"Public API for external integrations and automation. Connect your applications with WhatsApp, Telegram, Signal, Threema, SMS and more. Send messages, manage contacts, create broadcasts and automate your customer communication. \n\nFeatures:\n- Multi-channel messaging (WhatsApp, Telegram, Signal, Threema, SMS)\n- Contact management and tagging\n- Broadcast campaigns\n- Message templates and automation\n- Bot automation\n- QR code generation\n- URL shortening and tracking\n\n\nGetting Started:\n- [5-Minute Quickstart Tutorial](https://github.com/instantkom/api-examples#quickstart)\n- [Code Examples](https://github.com/instantkom/api-examples)\n\n\nAuthentication: Use your API Key from the instantKOM platform.","version":"3.186.1","contact":{"name":"instantKOM Support","url":"https://start.instantkom.app/persoenlicher-support/","email":"hallo@instantkom.app"},"termsOfService":"https://start.instantkom.app/agb/"},"tags":[{"name":"API Info","description":"API metadata and documentation links"},{"name":"Channels","description":"Messaging channels (WhatsApp, Telegram, SMS)"},{"name":"Contacts","description":"Manage contacts/subscribers in channels"},{"name":"Messages","description":"1:1 messages exchanged with contacts"},{"name":"Broadcasts","description":"Mass messages sent to multiple contacts"},{"name":"Tags","description":"Manage contact classification tags"},{"name":"Templates","description":"Message templates for quick messaging"},{"name":"Bots","description":"Automated messaging and workflow automation"},{"name":"ShortLinks","description":"URL shortening and click tracking"},{"name":"Segments","description":"Target groups and segmentation"},{"name":"Tickets","description":"Support tickets and customer inquiries"},{"name":"Flows","description":"Visual workflow automation for multi-bot orchestration"}],"servers":[{"url":"https://api.instantkom.app","description":"Production"},{"url":"http://localhost:3002","description":"Local Development"}],"components":{"securitySchemes":{"api-key":{"scheme":"bearer","bearerFormat":"API Key","type":"http","description":"Enter your API Key from the apis2 table"},"jwt":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Enter your JWT access token (obtained via /app/auth/login)"}},"schemas":{"ChannelKpisDto":{"type":"object","properties":{"totalContacts":{"type":"number","description":"Total number of contacts/recipients","example":1250},"activeContacts":{"type":"number","description":"Number of active contacts in the specified period","example":856},"messagesSent":{"type":"number","description":"Total messages sent in the specified period","example":3420},"messagesReceived":{"type":"number","description":"Total messages received in the specified period","example":2103},"deliveryRate":{"type":"number","description":"Message delivery rate as decimal (0-1)","example":0.975},"responseRate":{"type":"number","description":"Response rate as decimal (0-1)","example":0.615},"readRate":{"type":"number","description":"Message read rate as decimal (0-1)","example":0.842},"totalBroadcasts":{"type":"number","description":"Total number of broadcasts sent","example":45},"broadcastReach":{"type":"number","description":"Total broadcast recipients reached","example":15240},"broadcastDeliveryRate":{"type":"number","description":"Broadcast delivery rate as decimal (0-1)","example":0.981},"clickThroughRate":{"type":"number","description":"Click-through rate as decimal (0-1)","example":0.123},"errorRate":{"type":"number","description":"Error rate as decimal (0-1)","example":0.018},"newSubscribers":{"type":"number","description":"New subscribers in the specified period","example":124},"optOutRate":{"type":"number","description":"Opt-out rate as decimal (0-1)","example":0.021},"avgResponseTime":{"type":"number","description":"Average response time in seconds","example":245}},"required":["totalContacts","activeContacts","messagesSent","messagesReceived","deliveryRate","responseRate","readRate","totalBroadcasts","broadcastReach","broadcastDeliveryRate","clickThroughRate","errorRate","newSubscribers","optOutRate","avgResponseTime"]},"ChannelStatus":{"type":"string","enum":["inactive","active","test"],"description":"Channel lifecycle status"},"ChannelResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Channel ID","example":505},"externalId":{"type":"string","description":"External ID","example":"ABC1234567"},"name":{"type":"string","description":"Channel name","example":"Customer Support Channel"},"status":{"description":"Channel lifecycle status","example":"active","allOf":[{"$ref":"#/components/schemas/ChannelStatus"}]},"desiredStatus":{"description":"Desired operating state of the channel. Mirrors status and represents whether the channel should work.","example":"active","allOf":[{"$ref":"#/components/schemas/ChannelStatus"}]},"gatewayType":{"type":"string","description":"Gateway type (messaging platform)","example":"WhatsApp"},"gatewayTypeId":{"type":"number","description":"Gateway type ID","example":13},"isManageable":{"type":"boolean","description":"Whether this channel can be managed with operational controls such as active/inactive toggles","example":true},"activationStatus":{"description":"Activation status for channel types that require activation","example":"not_required","allOf":[{"$ref":"#/components/schemas/ChannelActivationStatus"}]},"availabilityStatus":{"description":"Central availability state derived from activation, provider connection, and gateway health.","example":"ready","allOf":[{"$ref":"#/components/schemas/ChannelAvailabilityStatus"}]},"availabilityReason":{"type":"string","description":"Machine-readable reason for the current availability state","example":"ready"},"canToggleDesiredStatus":{"type":"boolean","description":"Whether the user may change the desired operating state in list/detail controls","example":true},"canSend":{"type":"boolean","description":"Whether the channel is available and currently configured to send/work","example":true},"gatewayIcon":{"type":"string","description":"Gateway icon filename (from /imgs/imlogos/)","example":"whatsapp32.png"},"gatewayColor":{"type":"string","description":"Gateway brand color (hex without #)","example":"25D366"},"gatewayFontAwesome":{"type":"string","description":"Gateway FontAwesome icon name","example":"whatsapp"},"primaryContact":{"type":"object","description":"Primary contact information for the channel","example":{"identifier":"+49123456789","deepLinkUrl":"https://wa.me/+49123456789","isTest":false,"optInCommand":"start"}},"profileName":{"type":"string","description":"Profile name (WhatsApp Business profile name)","example":"Customer Support"},"profileDescription":{"type":"string","description":"Profile description","example":"Main customer support channel for product inquiries"},"profileIntro":{"type":"string","description":"Profile introduction message","example":"Welcome to our support channel!"},"profileWelcomeBack":{"type":"string","description":"Welcome back message (InstantChat only)","example":"Welcome back! How can we help you today?"},"profileCategory":{"type":"number","description":"Profile category (WhatsApp Business category ID)","example":1},"profileEmail":{"type":"string","description":"Profile email address","example":"support@example.com"},"website":{"type":"string","description":"Profile website URL","example":"https://example.com"},"profileWebsiteSecond":{"type":"string","description":"Profile second website URL","example":"https://support.example.com"},"profileAddress":{"type":"string","description":"Profile business address (composed single line)","example":"Hauptstrasse 1, 12345 Berlin"},"profileAddressStreet":{"type":"string","description":"Profile address: street"},"profileAddressHouseNumber":{"type":"string","description":"Profile address: house number"},"profileAddressZip":{"type":"string","description":"Profile address: postal code"},"profileAddressCity":{"type":"string","description":"Profile address: city"},"profileAddressCountry":{"type":"string","description":"Profile address: country"},"hasCustomProfileImage":{"type":"boolean","description":"Whether a custom profile image exists on disk for this channel (media/profiles/{externalId}.jpg). Resolved only on the single-channel endpoint; used to gate the WhatsApp ESU required-photo check.","example":true},"profileImageUpdatedAt":{"type":"number","description":"Profile image file mtime in milliseconds, used by the frontend to cache-bust the authenticated profile image endpoint.","example":1782036309000},"phoneNumber":{"type":"string","description":"WhatsApp phone number","example":"+4915112345678"},"countryCode":{"type":"string","description":"Country code","example":"DE"},"optinCommands":{"type":"string","description":"Opt-in command keywords (comma-separated)","example":"start,subscribe,join"},"optoutCommands":{"type":"string","description":"Opt-out command keywords (comma-separated)","example":"stop,unsubscribe,leave"},"deleteAllCommands":{"type":"string","description":"Delete all data command keywords (comma-separated)","example":"deleteall,forgetme"},"optinParameterStatus":{"type":"boolean","description":"Opt-in parameter enabled status","example":true},"optinParameterWordCount":{"type":"number","description":"Opt-in parameter word count","example":2},"optinParameterWordTargetField":{"type":"number","description":"Opt-in parameter word target field","example":1},"autoreplyOptinMessage":{"type":"string","description":"Autoreply message sent on opt-in","example":"Thank you for subscribing!"},"autoreplyDuplicateOptinMessage":{"type":"string","description":"Autoreply message sent on duplicate opt-in","example":"You are already subscribed."},"autoreplyOptoutMessage":{"type":"string","description":"Autoreply message sent on opt-out","example":"You have been unsubscribed."},"autoreplyDeleteAllMessage":{"type":"string","description":"Autoreply message sent on delete all","example":"All your data has been deleted."},"autoreplyOptinMediaId":{"type":"number","description":"Media ID for opt-in autoreply message","example":123},"autoreplyOptinMediaUrl":{"type":"string","description":"Media URL for opt-in autoreply message","example":"/media/uploads/image.jpg"},"autoreplyDuplicateOptinMediaId":{"type":"number","description":"Media ID for duplicate opt-in autoreply message","example":124},"autoreplyDuplicateOptinMediaUrl":{"type":"string","description":"Media URL for duplicate opt-in autoreply message","example":"/media/uploads/image2.jpg"},"autoreplyOptoutMediaId":{"type":"number","description":"Media ID for opt-out autoreply message","example":125},"autoreplyOptoutMediaUrl":{"type":"string","description":"Media URL for opt-out autoreply message","example":"/media/uploads/image3.jpg"},"autoreplyDeleteAllMediaId":{"type":"number","description":"Media ID for delete-all autoreply message","example":126},"autoreplyDeleteAllMediaUrl":{"type":"string","description":"Media URL for delete-all autoreply message","example":"/media/uploads/image4.jpg"},"autoreplyOptinMediaMimeType":{"type":"object","description":"MIME type of the opt-in autoreply media"},"autoreplyDuplicateOptinMediaMimeType":{"type":"object","description":"MIME type of the duplicate opt-in autoreply media"},"autoreplyOptoutMediaMimeType":{"type":"object","description":"MIME type of the opt-out autoreply media"},"autoreplyDeleteAllMediaMimeType":{"type":"object","description":"MIME type of the delete-all autoreply media"},"chatsOpenOnMessage":{"type":"boolean","description":"Automatically open chat on incoming message","example":true},"chatsFilterReactions":{"type":"boolean","description":"Filter out reaction messages in chats","example":false},"chatsFilterTextReply":{"type":"boolean","description":"Filter out text reply messages in chats","example":false},"mailForwardMessages":{"type":"boolean","description":"Email forwarding enabled","example":false},"mailForwardMessagesFilterBot":{"type":"boolean","description":"Email forward: filter bot messages","example":true},"mailForwardMessagesFilterPoll":{"type":"boolean","description":"Email forward: filter poll messages","example":true},"mailForwardMessagesFilterReaction":{"type":"boolean","description":"Email forward: filter reaction messages","example":true},"mailForwardMessagesFilterReply":{"type":"boolean","description":"Email forward: filter text reply messages","example":true},"mailForwardMessagesInterval":{"type":"number","description":"Email forward interval in minutes","example":15},"mailForwardMessagesEmail":{"type":"string","description":"Email forward target address","example":"notifications@example.com"},"messengerForwardMessages":{"type":"boolean","description":"Messenger forwarding enabled","example":false},"messengerForwardMessagesFilterBot":{"type":"boolean","description":"Messenger forward: filter bot messages","example":true},"messengerForwardMessagesFilterPoll":{"type":"boolean","description":"Messenger forward: filter poll messages","example":true},"messengerForwardMessagesFilterReaction":{"type":"boolean","description":"Messenger forward: filter reaction messages","example":true},"messengerForwardMessagesFilterReply":{"type":"boolean","description":"Messenger forward: filter text reply messages","example":true},"messengerForwardMessagesTargets":{"type":"string","description":"Messenger forward target numbers (comma-separated)","example":"+4915112345678,+4915187654321"},"messengerForwardMessagesAuthcode":{"type":"string","description":"Messenger forward authorization code","example":"AUTH123CODE"},"ikm2mailForwardStatus":{"type":"boolean","description":"IKM2Mail forwarding enabled","example":false},"ikm2mailForwardFilterBot":{"type":"boolean","description":"IKM2Mail forward: filter bot messages","example":true},"ikm2mailForwardFilterPoll":{"type":"boolean","description":"IKM2Mail forward: filter poll messages","example":true},"ikm2mailForwardFilterReactions":{"type":"boolean","description":"IKM2Mail forward: filter reaction messages","example":true},"ikm2mailForwardFilterTextReply":{"type":"boolean","description":"IKM2Mail forward: filter text reply messages","example":true},"ikm2mailForwardSkipChatOpen":{"type":"boolean","description":"IKM2Mail forward: skip messages when chat is open","example":false},"ikm2mailForwardResendStatus":{"type":"boolean","description":"IKM2Mail forward: resend enabled","example":false},"ikm2mailForwardEmail":{"type":"string","description":"IKM2Mail forward target email address","example":"support@example.com"},"ikm2mailForwardEmailStrict":{"type":"boolean","description":"IKM2Mail forward: strict email validation","example":false},"ikm2mailForwardAttachments":{"type":"boolean","description":"IKM2Mail forward: include attachments","example":true},"ikm2mailForwardAttachmentsReverse":{"type":"boolean","description":"IKM2Mail forward: reverse attachment order","example":false},"ikm2mailForwardHistory":{"type":"number","description":"IKM2Mail forward: number of history messages to include","example":5},"ikm2mailForwardHistoryFontSize":{"type":"boolean","description":"IKM2Mail forward: use smaller font size for history","example":true},"ticketSystemStatus":{"type":"boolean","description":"Ticket system enabled","example":false},"ticketSystemBypassBot":{"type":"boolean","description":"Ticket system: bypass for bot messages","example":false},"ticketSystemBypassReactions":{"type":"boolean","description":"Ticket system: bypass for reaction messages","example":true},"ticketSystemBypassTextReply":{"type":"boolean","description":"Ticket system: bypass for text reply messages","example":false},"ticketSystemAlwaysNew":{"type":"boolean","description":"Ticket system: always create new ticket","example":false},"ticketSystemAlwaysNewThreshold":{"type":"number","description":"Ticket system: threshold for creating new ticket (minutes)","example":1440},"ticketSystemAttachClosed":{"type":"boolean","description":"Ticket system: attach closed ticket messages","example":false},"ticketSystemAssignReplyStatus":{"type":"boolean","description":"Ticket system: send reply on ticket assignment","example":false},"ticketSystemAssignReplyMessage":{"type":"string","description":"Ticket system: assignment reply message","example":"Your ticket has been assigned to a team member."},"ticketSystemCloseReplyStatus":{"type":"boolean","description":"Ticket system: send reply on ticket closure","example":false},"ticketSystemCloseReplyMessage":{"type":"string","description":"Ticket system: closure reply message","example":"Your ticket has been closed."},"testIdentifier":{"type":"string","description":"Admin/test phone number for testing","example":"+4915112345678"},"sendHideUrlPreview":{"type":"boolean","description":"Hide URL previews in sent messages","example":false},"sendProtectContent":{"type":"boolean","description":"Protect content from forwarding (Telegram)","example":false},"sendSilently":{"type":"boolean","description":"Send messages silently without notification","example":false},"highPerformance":{"type":"boolean","description":"High performance mode enabled","example":false},"spamFilterEnabled":{"type":"boolean","description":"AI spam filter enabled for incoming messages","example":false},"autoDeactivation":{"type":"number","description":"Auto-deactivation threshold (fail attempts)","example":10},"views":{"type":"number","description":"Number of views/impressions","example":1250},"subscribers":{"type":"number","description":"Number of subscribers","example":432},"isPublic":{"type":"boolean","description":"Public visibility status","example":true},"isVerified":{"type":"boolean","description":"Verification status","example":true},"createdAt":{"type":"string","description":"Channel creation date (ISO 8601)","example":"2025-01-15T10:30:00.000Z"},"activatedAt":{"type":"string","description":"Channel activation date (ISO 8601)","example":"2025-01-15T12:00:00.000Z"},"updatedAt":{"type":"string","description":"Last update date (ISO 8601)","example":"2025-11-12T08:45:00.000Z"},"offReason":{"type":"string","description":"Reason why the channel was deactivated (e.g. free_plan)","example":"free_plan"},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["id","externalId","name","status","desiredStatus","gatewayType","gatewayTypeId","isManageable","activationStatus","availabilityStatus","availabilityReason","canToggleDesiredStatus","canSend","chatsOpenOnMessage","chatsFilterReactions","chatsFilterTextReply","mailForwardMessages","mailForwardMessagesFilterBot","mailForwardMessagesFilterPoll","mailForwardMessagesFilterReaction","mailForwardMessagesFilterReply","messengerForwardMessages","messengerForwardMessagesFilterBot","messengerForwardMessagesFilterPoll","messengerForwardMessagesFilterReaction","messengerForwardMessagesFilterReply","ikm2mailForwardStatus","ikm2mailForwardFilterBot","ikm2mailForwardFilterPoll","ikm2mailForwardFilterReactions","ikm2mailForwardFilterTextReply","ikm2mailForwardSkipChatOpen","ikm2mailForwardResendStatus","ikm2mailForwardEmailStrict","ikm2mailForwardAttachments","ikm2mailForwardAttachmentsReverse","ikm2mailForwardHistoryFontSize","ticketSystemStatus","ticketSystemBypassBot","ticketSystemBypassReactions","ticketSystemBypassTextReply","ticketSystemAlwaysNew","ticketSystemAttachClosed","ticketSystemAssignReplyStatus","ticketSystemCloseReplyStatus","sendHideUrlPreview","sendProtectContent","sendSilently","highPerformance","spamFilterEnabled","views","subscribers","isPublic","isVerified","createdAt","updatedAt"]},"GatewayType":{"type":"string","enum":[0,2,3,4,5,6,7,8,9,11,13,14,15,16,17,18,19]},"CreateChannelDto":{"type":"object","properties":{"name":{"type":"string","description":"Channel name","example":"Customer Support WhatsApp","maxLength":80},"gatewayType":{"type":"number","description":"Gateway type ID (2=SMS, 3=Telegram, 4=Facebook Messenger, 5=QuickKOM, 6=Threema, 7=InstantChat, 8=Viber, 9=Instagram, 11=Twitter, 13=WhatsApp, 14=ABC, 15=ICQ, 16=Signal, 17=WhatsApp Cloud API, 18=Email, 19=RCS)","example":13,"enum":[0,2,3,4,5,6,7,8,9,11,13,14,15,16,17,18,19]},"description":{"type":"string","description":"Channel description","example":"Main customer support channel","maxLength":200},"introduction":{"type":"string","description":"Introduction message","example":"Welcome to our support!"},"phoneNumber":{"type":"string","description":"WhatsApp phone number","example":"+4915112345678","maxLength":30},"countryCode":{"type":"string","description":"Country code","example":"DE","maxLength":2},"website":{"type":"string","description":"Website URL","example":"https://example.com","maxLength":250},"email":{"type":"string","description":"Email address","example":"support@example.com","maxLength":250},"address":{"type":"string","description":"Business address","example":"Hauptstrasse 1, 12345 Berlin","maxLength":250},"status":{"description":"Channel lifecycle status","example":"active","allOf":[{"$ref":"#/components/schemas/ChannelStatus"}]},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["name","gatewayType"]},"UpdateChannelDto":{"type":"object","properties":{"name":{"type":"string","description":"Channel name","example":"Customer Support WhatsApp","maxLength":80},"description":{"type":"string","description":"Channel description","example":"Main customer support channel","maxLength":200},"introduction":{"type":"string","description":"Introduction message","example":"Welcome to our support!"},"phoneNumber":{"type":"string","description":"WhatsApp phone number","example":"+4915112345678","maxLength":30},"countryCode":{"type":"string","description":"Country code","example":"DE","maxLength":2},"website":{"type":"string","description":"Website URL","example":"https://example.com","maxLength":250},"email":{"type":"string","description":"Email address","example":"support@example.com","maxLength":250},"address":{"type":"string","description":"Business address","example":"Hauptstrasse 1, 12345 Berlin","maxLength":250},"addressStreet":{"type":"string","description":"Profile address: street","maxLength":150},"addressHouseNumber":{"type":"string","description":"Profile address: house number","maxLength":30},"addressZip":{"type":"string","description":"Profile address: postal code","maxLength":20},"addressCity":{"type":"string","description":"Profile address: city","maxLength":120},"addressCountry":{"type":"string","description":"Profile address: country","maxLength":80},"category":{"type":"number","description":"WhatsApp Business profile category ID (0-16)","example":1,"minimum":0,"maximum":16},"websiteSecond":{"type":"string","description":"Secondary website URL","example":"https://shop.example.com","maxLength":250},"welcomeBack":{"type":"string","description":"Welcome back message (InstantChat only)","example":"Welcome back! How can we help you today?","maxLength":1000},"status":{"description":"Channel lifecycle status","example":"active","allOf":[{"$ref":"#/components/schemas/ChannelStatus"}]},"optinCommands":{"type":"string","description":"Opt-in command keywords (comma-separated)","example":"start,subscribe,join","maxLength":250},"optoutCommands":{"type":"string","description":"Opt-out command keywords (comma-separated)","example":"stop,unsubscribe,leave","maxLength":250},"deleteAllCommands":{"type":"string","description":"Delete all data command keywords (comma-separated)","example":"deleteall,forgetme","maxLength":250},"optinParameterStatus":{"type":"boolean","description":"Opt-in parameter enabled status","example":true},"optinParameterWordCount":{"type":"number","description":"Opt-in parameter word count","example":2},"spamFilterEnabled":{"type":"boolean","description":"AI spam filter enabled for incoming messages","example":true},"chatsOpenOnMessage":{"type":"boolean","description":"Automatically open chats when a new message arrives","example":true},"chatsFilterReactions":{"type":"boolean","description":"Filter reaction messages from chat views","example":true},"chatsFilterTextReply":{"type":"boolean","description":"Filter text reply messages from chat views","example":false},"sendHideUrlPreview":{"type":"boolean","description":"Hide URL previews in outgoing Telegram messages","example":false},"sendProtectContent":{"type":"boolean","description":"Protect outgoing Telegram message content","example":false},"sendSilently":{"type":"boolean","description":"Send outgoing Telegram messages silently","example":false},"highPerformance":{"type":"boolean","description":"Enable high-performance Telegram sending","example":false},"autoreplyOptinMessage":{"type":"string","description":"Autoreply message sent on opt-in","example":"Thank you for subscribing!"},"autoreplyOptinMediaId":{"type":"object","description":"Media ID for opt-in autoreply message","example":123},"autoreplyDuplicateOptinMessage":{"type":"string","description":"Autoreply message sent on duplicate opt-in","example":"You are already subscribed."},"autoreplyDuplicateOptinMediaId":{"type":"object","description":"Media ID for duplicate opt-in autoreply message","example":124},"autoreplyOptoutMessage":{"type":"string","description":"Autoreply message sent on opt-out","example":"You have been unsubscribed."},"autoreplyOptoutMediaId":{"type":"object","description":"Media ID for opt-out autoreply message","example":125},"autoreplyDeleteAllMessage":{"type":"string","description":"Autoreply message sent on delete all","example":"All your data has been deleted."},"autoreplyDeleteAllMediaId":{"type":"object","description":"Media ID for delete-all autoreply message","example":126},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"PaginatedResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Success status of the request","example":true},"data":{"type":"object","description":"Response data"},"message":{"type":"string","description":"Error message if success is false"},"timestamp":{"type":"string","description":"ISO 8601 timestamp of the response","example":"2025-11-12T12:00:00.000Z"},"pagination":{"type":"object","description":"Pagination metadata"}},"required":["success","timestamp","pagination"]},"RecipientBotEnvValueDto":{"type":"object","properties":{"id":{"type":"number","description":"Environment value ID","example":12},"key":{"type":"string","description":"Environment variable key","example":"CUSTOMER_ID"},"value":{"type":"string","description":"Current value","example":"4711"},"description":{"type":"string","description":"Environment variable description","example":"Customer identifier used by bots"},"color":{"type":"string","description":"Display color from the environment variable definition","example":"#0EA5E9"},"createdAt":{"type":"string","description":"Creation timestamp (ISO 8601)","example":"2026-04-15T09:30:00.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2026-04-16T10:45:00.000Z"},"expiresAt":{"type":"string","description":"Expiration timestamp (ISO 8601)","example":"2026-04-30T23:59:59.000Z"}},"required":["id","key","value"]},"RecipientTagAssignmentDto":{"type":"object","properties":{"id":{"type":"number","description":"Tag assignment ID","example":501},"tagId":{"type":"number","description":"Tag ID","example":42},"name":{"type":"string","description":"Tag name","example":"VIP"},"color":{"type":"string","description":"Tag color (hex)","example":"#3B82F6"}},"required":["id","tagId","name","color"]},"RecipientSegmentDto":{"type":"object","properties":{"id":{"type":"number","description":"Segment ID","example":42},"name":{"type":"string","description":"Segment name","example":"VIP Customers"},"color":{"type":"string","description":"Segment display color","example":"#3498db"}},"required":["id","name"]},"RecipientResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Recipient ID","example":12345},"channelId":{"type":"number","description":"Channel ID this recipient belongs to","example":505},"identifier":{"type":"string","description":"Unique identifier for this contact (phone number for WhatsApp/SMS, user ID for Telegram, Threema ID for Threema, etc.)","example":"+491511234567"},"countryCode":{"type":"string","description":"Country code (ISO 3166-1 alpha-2)","example":"DE"},"name":{"type":"string","description":"Recipient name","example":"Max Mustermann"},"nickname":{"type":"string","description":"Nickname/alias","example":"Max"},"notes":{"type":"string","description":"Internal notes about this recipient","example":"VIP customer"},"optinParam":{"type":"string","description":"Opt-in parameter captured during opt-in","example":"newsletter"},"optedIn":{"type":"boolean","description":"Opt-in status (true if opted in, false if opted out or not yet opted in)","example":true},"state":{"type":"number","description":"Subscription state (0=OPTOUT, 1=OPTIN, 2=SIGNIN/imported, 3=DIALOG)","enum":[0,1,2,3],"example":1},"optinTimestamp":{"type":"string","description":"Opt-in timestamp (ISO 8601)","example":"2025-01-15T10:30:00.000Z"},"importTimestamp":{"type":"string","description":"Import/sign-in timestamp (ISO 8601)","example":"2025-01-10T08:00:00.000Z"},"optoutTimestamp":{"type":"string","description":"Opt-out timestamp (ISO 8601)","example":null},"autoDeactivationTimestamp":{"type":"string","description":"Auto-deactivation timestamp (ISO 8601)","example":null},"delallTimestamp":{"type":"string","description":"Delete-all timestamp (ISO 8601)","example":null},"delallQueued":{"type":"boolean","description":"Delete-all queued status","example":false},"blocked":{"type":"boolean","description":"Blocked status","example":false},"isSpam":{"type":"boolean","description":"Spam status (true if contact is flagged as spam)","example":false},"isTestRecipient":{"type":"boolean","description":"Test recipient pool flag (true if contact is flagged as a test-newsletter recipient)","example":false},"trustLevel":{"type":"string","description":"Trust level computed synchronously from manual overrides (blocked/whitelisted) and auto signals (spam, reply history, opt-in). Manual overrides win.","enum":["blocked","whitelisted","spam","suspicious","trusted","unknown"],"example":"trusted"},"trustSource":{"type":"string","description":"Trust source: \"manual\" if blocked or whitelisted by a user, \"auto\" otherwise.","enum":["auto","manual"],"example":"auto"},"trustReason":{"type":"string","description":"Short i18n key describing why this trust level was assigned (e.g. \"team_replied\", \"inbound_no_reply\", \"optin_confirmed\", \"spam_flag\", \"opted_out\").","example":"team_replied"},"trustUpdatedAt":{"type":"string","description":"When the trust override was last set (ISO 8601). Only set for manual overrides.","example":"2026-04-08T09:15:00.000Z"},"trustUpdatedBy":{"type":"number","description":"User ID who set the manual trust override (audit trail).","example":42},"lastSeenAt":{"type":"string","description":"Last seen date (ISO 8601)","example":"2025-11-10T15:22:00.000Z"},"botEnvValues":{"description":"Recipient-specific bot environment values shown on the profile tab","type":"array","items":{"$ref":"#/components/schemas/RecipientBotEnvValueDto"}},"recovery":{"description":"Recipient recovery metadata","allOf":[{"$ref":"#/components/schemas/RecipientRecoveryDto"}]},"statistics":{"type":"object","description":"Message statistics"},"lastMessageAt":{"type":"object","description":"Timestamp of the last message (ISO 8601)","example":"2024-12-17T14:30:00.000Z"},"lastActivityAt":{"type":"object","description":"Canonical list activity timestamp. Prefers last message, then last seen, last update, and creation timestamp.","example":"2024-12-17T14:30:00.000Z"},"messagesLast7Days":{"type":"number","description":"Number of messages in the last 7 days","example":25},"messagesLast30Days":{"type":"number","description":"Number of messages in the last 30 days","example":85},"messagesByDay":{"type":"array","description":"Daily message counts for the last 30 days","items":{"type":"object","properties":{"date":{"type":"string","description":"Date (YYYY-MM-DD)","example":"2024-12-01"},"sent":{"type":"number","description":"Messages sent","example":3},"received":{"type":"number","description":"Messages received","example":2}}},"example":[{"date":"2024-12-01","sent":3,"received":2},{"date":"2024-12-02","sent":5,"received":3}]},"tags":{"type":"string","description":"Tags (comma-separated)","example":"vip,newsletter,customer"},"tagAssignments":{"description":"Embedded tag assignments (id, tagId, name, color). Present on list responses so clients do not need one GET /contacts/:id/tags request per row.","type":"array","items":{"$ref":"#/components/schemas/RecipientTagAssignmentDto"}},"segments":{"description":"Segments this contact belongs to based on the segment tag rules.","type":"array","items":{"$ref":"#/components/schemas/RecipientSegmentDto"}},"chatWindow":{"type":"object","description":"WhatsApp 24-hour messaging window status (only for WhatsApp channels)"},"customFields":{"type":"array","description":"Custom field values for this contact","items":{"type":"object","properties":{"fieldId":{"type":"number","description":"Custom field definition ID"},"fieldKey":{"type":"string","description":"Field key"},"fieldName":{"type":"string","description":"Field name"},"fieldType":{"type":"string","description":"Field type"},"value":{"type":"string","description":"Field value"},"updatedAt":{"type":"string","description":"Last update timestamp"}}}},"createdAt":{"type":"string","description":"Recipient creation date (ISO 8601)","example":"2025-01-10T08:15:00.000Z"},"updatedAt":{"type":"string","description":"Recipient last update date (ISO 8601)","example":"2025-06-15T14:30:00.000Z"},"quality":{"description":"Quality score based on message engagement (read/received vs sent)","allOf":[{"$ref":"#/components/schemas/QualityDto"}]},"folderId":{"type":"number","description":"Object folder ID","example":1},"hasAvatar":{"type":"boolean","description":"Whether the recipient has a profile picture on file","example":false}},"required":["id","channelId","identifier","optedIn","state","delallQueued","blocked","isSpam","isTestRecipient","trustLevel","trustSource","statistics","createdAt","hasAvatar"]},"CreateRecipientDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID the recipient belongs to","example":505},"identifier":{"type":"string","description":"Unique identifier for this contact (phone number for WhatsApp/SMS, user ID for Telegram, Threema ID for Threema, etc.)","example":"+491701234567"},"name":{"type":"string","description":"Recipient name","example":"Max Mustermann"},"optinStatus":{"type":"number","description":"Opt-in status","enum":[0,1,2,3],"example":1},"isBlocked":{"type":"boolean","description":"Whether the recipient is blocked","example":false},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["channelId","identifier"]},"UpdateRecipientDto":{"type":"object","properties":{"nickname":{"type":"string","description":"Nickname","example":"Maxi"},"notes":{"type":"string","description":"Notes","example":"VIP customer"},"optinStatus":{"type":"number","description":"Opt-in status","enum":[0,1,2,3],"example":1},"isBlocked":{"type":"boolean","description":"Whether the recipient is blocked","example":false},"optinParam":{"type":"string","description":"Opt-in parameter (source/campaign identifier)","example":"newsletter-2024"},"tags":{"type":"string","description":"Tags (comma-separated)","example":"vip,newsletter"},"folderId":{"type":"number","description":"Object folder ID","example":1},"isSpam":{"type":"boolean","description":"Spam status override - manually mark/unmark as spam","example":false}}},"AddTagDto":{"type":"object","properties":{"tagId":{"type":"number","description":"Tag ID to assign to the recipient","example":123,"minimum":1}},"required":["tagId"]},"TagAssignmentResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Tag assignment ID","example":456},"tagId":{"type":"number","description":"Tag ID","example":123},"recipientId":{"type":"number","description":"Recipient ID","example":789},"name":{"type":"string","description":"Tag name","example":"VIP Customer"},"color":{"type":"string","description":"Tag color (hex)","example":"#FF5733"},"assignedAt":{"type":"string","description":"Assignment timestamp (ISO 8601)","example":"2024-01-15T10:30:00.000Z"}},"required":["id","tagId","recipientId","name","color"]},"MessageResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Message ID","example":395344},"externalId":{"type":"string","description":"External ID","example":"FwDVCfDCp2"},"recipientId":{"type":"number","description":"Recipient ID","example":81857},"recipientName":{"type":"string","description":"Recipient name","example":"Max Mustermann"},"recipientIdentifier":{"type":"string","description":"Recipient phone number or identifier","example":"+491701234567"},"channelId":{"type":"number","description":"Channel ID","example":505},"channelName":{"type":"string","description":"Channel name","example":"WhatsApp Business"},"message":{"type":"string","description":"Message content","example":"Hello, how can I help you?"},"messageType":{"type":"string","description":"Message type","enum":["text","image","video","audio","document","location","contact","sticker"],"example":"text"},"direction":{"type":"string","description":"Message direction (sent or received)","enum":["sent","received"],"example":"received"},"status":{"description":"Message status","example":"pending","allOf":[{"$ref":"#/components/schemas/MessageStatus"}]},"buttons":{"type":"object","description":"Interactive buttons (JSON array)","example":null},"headerFooter":{"type":"object","description":"Header and footer content (JSON object)","example":null},"whatsappMessageId":{"type":"string","description":"WhatsApp Message ID","example":"513371295"},"errorDescription":{"type":"string","description":"Error description if message failed","example":null},"deliveryError":{"type":"string","description":"Canonical asynchronous delivery error code","example":"euna"},"providerCode":{"type":"string","description":"Raw delivery provider error code","example":"5.1.1"},"providerDesc":{"type":"string","description":"Raw delivery provider error description","example":"Mailbox unavailable"},"locked":{"type":"boolean","description":"Message locked status (read-only)","example":false},"hidden":{"type":"boolean","description":"Message hidden status","example":false},"isSpam":{"type":"boolean","description":"Message spam status (marked as spam by user)","example":false},"createdAt":{"type":"string","description":"Message creation date (ISO 8601)","example":"2020-03-10T09:50:09.000Z"},"queuedAt":{"type":"string","description":"Message queued date (ISO 8601). Present when message is scheduled for future delivery.","example":"2020-03-10T09:50:05.000Z"},"scheduledAt":{"type":"string","description":"Scheduled send time (ISO 8601). Present when message is scheduled for future delivery. If not set, message will be sent immediately.","example":"2025-01-15T10:00:00.000Z"},"timestamp":{"type":"string","description":"Message sent/received timestamp (ISO 8601)","example":"2020-03-10T09:50:09.000Z"},"readAt":{"type":"string","description":"Message read timestamp (ISO 8601)","example":"2020-03-10T09:50:10.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2020-03-10T09:50:09.000Z"},"media":{"description":"Media attachment if message contains media","allOf":[{"$ref":"#/components/schemas/MediaMediaResponseDto"}]},"ticket":{"description":"Linked ticket reference for messages that created or belong to a ticket","allOf":[{"$ref":"#/components/schemas/MessageTicketReferenceDto"}]},"buttonLabel":{"type":"string","description":"For messageType=\"button\": parsed button label (e.g. \"Antwort 1\"). Used to render readable content instead of raw JSON.","example":"Antwort 1"},"buttonPayload":{"type":"string","description":"For messageType=\"button\": button payload (debug/automation use).","example":"SOTHYS_BOX_INFO"}},"required":["id","externalId","recipientId","message","messageType","direction","status","locked","hidden","isSpam","createdAt","timestamp","updatedAt"]},"CreateMessageDto":{"type":"object","properties":{"recipientId":{"type":"number","description":"Recipient ID","example":12345},"message":{"type":"string","description":"Message content","example":"Hello, this is a test message"},"messageType":{"type":"string","description":"Message type","enum":["text","image","video","audio","document","location"],"example":"text"},"buttons":{"type":"object","description":"Content buttons (JSON array)","example":[]},"headerFooter":{"type":"object","description":"Header/Footer content (JSON object)","example":{}},"isLocked":{"type":"boolean","description":"Whether the message should be locked","example":false,"default":false},"scheduledAt":{"type":"number","description":"Schedule message for future send (Unix timestamp in seconds). If not set, the message is sent immediately. Must be a future timestamp.","example":1735000000},"latitude":{"type":"number","description":"Latitude for location messages (-90 to 90)","example":52.520008},"longitude":{"type":"number","description":"Longitude for location messages (-180 to 180)","example":13.404954},"locationName":{"type":"string","description":"Location name/label for location messages (max 255 chars, no HTML)","example":"Berlin Office"},"templateId":{"type":"number","description":"WhatsApp template ID. When set, the message is sent as an approved template, bypassing the 24-hour messaging window. The template must be active (wab_template_sts=3) and belong to the same channel as the recipient.","example":491}},"required":["recipientId","message","messageType"]},"BulkMarkSpamDto":{"type":"object","properties":{"messageIds":{"description":"Array of message IDs to update (maximum 100)","example":[1,2,3],"type":"array","items":{"type":"number"}},"isSpam":{"type":"boolean","description":"Whether to mark the messages as spam (true) or not spam (false)","example":true}},"required":["messageIds","isSpam"]},"UpdateMessageDto":{"type":"object","properties":{"message":{"type":"string","description":"Message content","example":"Updated message content"},"buttons":{"type":"object","description":"Content buttons (JSON array)","example":[]},"headerFooter":{"type":"object","description":"Header/Footer content (JSON object)","example":{}},"isLocked":{"type":"boolean","description":"Whether the message is locked","example":false},"isHidden":{"type":"boolean","description":"Whether the message is hidden","example":false},"scheduledAt":{"type":"number","description":"Reschedule message for future send (Unix timestamp in seconds). Only updateable if message has not been sent yet (dtsr = 0). Must be a future timestamp.","example":1735000000}}},"MarkSpamDto":{"type":"object","properties":{"isSpam":{"type":"boolean","description":"Whether to mark the message as spam (true) or not spam (false)","example":true}},"required":["isSpam"]},"CreateTicketFromMessageDto":{"type":"object","properties":{"subject":{"type":"string","description":"Ticket subject (auto-generated from message if not provided)","example":"Support Request"},"priority":{"description":"Ticket priority","example":"normal","allOf":[{"$ref":"#/components/schemas/TicketPriority"}]},"assignedTo":{"type":"number","description":"User ID to assign the ticket to","example":1}}},"TicketResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Ticket ID","example":1},"channelId":{"type":"number","description":"Associated channel ID","example":1},"ticketId":{"type":"string","description":"Ticket reference ID","example":"TKT-2024-001"},"subject":{"type":"string","description":"Ticket subject/title","example":"Issue with message delivery"},"email":{"type":"string","description":"Customer email address","example":"customer@example.com"},"recipientId":{"type":"number","description":"Associated recipient ID","example":12345},"recipient":{"type":"object","description":"Associated recipient (contact) details","example":{"id":12345,"name":"Max Mustermann","nickname":null,"identifier":"+491701234567","countryCode":"DE","hasAvatar":false}},"name":{"type":"string","description":"Customer name","example":"John Doe"},"title":{"type":"string","description":"Customer title/salutation","example":"Premium Customer"},"gender":{"description":"Customer gender","example":"unknown","allOf":[{"$ref":"#/components/schemas/Gender"}]},"company":{"type":"string","description":"Company name","example":"Acme Corp"},"status":{"description":"Ticket status","example":"open","allOf":[{"$ref":"#/components/schemas/TicketStatus"}]},"priority":{"description":"Ticket priority","example":"normal","allOf":[{"$ref":"#/components/schemas/TicketPriority"}]},"userId":{"type":"number","description":"User ID who created the ticket","example":1},"assignedTo":{"type":"number","description":"User ID who is assigned to the ticket","example":1},"assignedUser":{"type":"object","description":"Assigned user details","example":{"id":1,"name":"Anna Schneider","username":"anna.schneider","avatarUrl":"/api/proxy/app/media/users/abc123/avatar","color":"#3B82F6"}},"source":{"type":"string","description":"Source of ticket (e.g. email, whatsapp, telegram)","example":"email"},"recipients":{"type":"string","description":"Additional recipients (comma-separated)"},"spamScore":{"type":"number","description":"Spam score (0-1)","example":0.05},"isSpam":{"type":"boolean","description":"Is marked as spam","example":false},"chatWindow":{"type":"object","description":"WhatsApp 24-hour messaging window status (for WhatsApp channels)"},"createdAt":{"type":"string","description":"Created at (ISO 8601)","example":"2023-11-13T10:15:43Z"},"updatedAt":{"type":"string","description":"Last updated at (ISO 8601)","example":"2023-11-13T10:15:43Z"},"closedAt":{"type":"string","description":"Closed at (ISO 8601)","example":"2023-11-14T12:00:00Z"},"channel":{"type":"object","description":"Associated channel details"},"messageCount":{"type":"number","description":"Total number of messages in ticket","example":15},"customerMessageCount":{"type":"number","description":"Number of customer messages (incoming)","example":8},"agentMessageCount":{"type":"number","description":"Number of agent messages (outgoing)","example":7},"firstResponseAt":{"type":"string","description":"First response timestamp (ISO 8601)","example":"2023-11-13T10:45:00Z"},"firstResponseTimeSeconds":{"type":"number","description":"Time to first response in seconds","example":1800},"avgResponseTimeSeconds":{"type":"number","description":"Average response time in seconds","example":3600},"lastActivityAt":{"type":"string","description":"Last activity timestamp (ISO 8601)","example":"2023-11-14T09:30:00Z"},"messagesByDay":{"description":"Messages per day for the last 30 days","example":[{"date":"2023-11-13","count":5},{"date":"2023-11-14","count":3}],"type":"array","items":{"type":"string"}},"qualityScore":{"type":"number","description":"Quality score (0-100) based on response time and resolution","example":85},"folderId":{"type":"number","description":"Object folder ID","example":1},"createdBy":{"type":"string","description":"Name of the user who created the ticket","example":"Anna Schneider"}},"required":["id","channelId","ticketId","subject","email","name","gender","status","priority","userId","spamScore","isSpam","createdAt","updatedAt"]},"TicketMessageMediaAttachmentDto":{"type":"object","properties":{"id":{"type":"number","description":"Attachment ID","example":42},"uri":{"type":"string","description":"Authenticated media download URL","example":"/app/media/messages/42/download?attachmentId=7"},"type":{"type":"string","description":"Attachment type","example":"image"},"scanStatus":{"type":"string","description":"Persisted AV scan verdict","example":"clean"}},"required":["id","uri"]},"TicketMessageResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Message ID","example":1},"ticketId":{"type":"number","description":"Associated ticket ID","example":1},"message":{"type":"string","description":"Message content","example":"Thank you for contacting support."},"direction":{"type":"string","description":"Transaction type (in=incoming, out=outgoing)","example":"out"},"authorId":{"type":"number","description":"Author ID (user or recipient)","example":1},"createdAt":{"type":"string","description":"Created at (ISO 8601)","example":"2023-11-13T10:15:43Z"},"mediaUri":{"type":"object","description":"Media download URL for image/video/audio messages (null if text-only)","example":"/app/media/messages/42/download","nullable":true},"mediaType":{"type":"object","description":"Attachment type (image, video, audio, document, etc.)","example":"image","nullable":true},"mediaScanStatus":{"type":"object","description":"AV scan verdict of the attachment ('infected' | 'unscanned' | 'clean'); drives the malware badge (#5001)","example":"infected","nullable":true},"mediaAttachments":{"description":"All attachments linked to the source message, ordered by ID","type":"array","items":{"$ref":"#/components/schemas/TicketMessageMediaAttachmentDto"}}},"required":["id","ticketId","message","direction","authorId","createdAt"]},"CreateTicketFromMessageResponseDto":{"type":"object","properties":{"ticket":{"description":"Created ticket","allOf":[{"$ref":"#/components/schemas/TicketResponseDto"}]},"ticketMessage":{"description":"Created ticket message","allOf":[{"$ref":"#/components/schemas/TicketMessageResponseDto"}]},"sourceMessage":{"description":"Source message that was converted","allOf":[{"$ref":"#/components/schemas/SourceMessageDto"}]}},"required":["ticket","ticketMessage","sourceMessage"]},"BroadcastTargetDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID","example":505},"segmentId":{"type":"number","description":"Segment ID (null/undefined = all contacts in channel)","example":123}},"required":["channelId"]},"BroadcastSendStatus":{"type":"string","enum":["draft","scheduled","sending","sent","failed"],"description":"Send status"},"CreateBroadcastDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID to send broadcast to. Required if \"targets\" is not provided. Use this for a single channel, or use \"targets\" for multiple channels.","example":505},"segmentId":{"type":"number","description":"Segment ID to target specific contacts (null = all contacts in channel)","example":123},"targets":{"description":"Multiple targets (channel/segment combinations). Required if \"channelId\" is not provided. Creates one broadcast per target.","example":[{"channelId":505,"segmentId":123},{"channelId":506}],"type":"array","items":{"$ref":"#/components/schemas/BroadcastTargetDto"}},"message":{"type":"string","description":"Broadcast message content","example":"Hello everyone! This is our latest news update.","maxLength":4096},"broadcastType":{"type":"string","description":"Broadcast type","enum":["text","image","video","audio","document"],"default":"text","example":"text"},"scheduledAt":{"type":"number","description":"Schedule broadcast for future send (Unix timestamp)","example":1735000000},"test":{"type":"boolean","description":"Test broadcast flag","default":false,"example":false},"autoApprove":{"type":"boolean","description":"Auto-approve broadcast (requires permission)","default":false,"example":false},"shortlinks":{"type":"boolean","description":"Render links in the message as tracked shortlinks. Requires the SHORTLINKS plan feature (f_shortlinks); a true value without the feature is rejected with 403.","default":false,"example":false},"sendStatus":{"description":"Send status","default":"draft","example":"draft","allOf":[{"$ref":"#/components/schemas/BroadcastSendStatus"}]},"mediaIds":{"description":"Media file UUIDs to attach to broadcast","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string"}},"libraryMediaId":{"type":"number","description":"Media library item ID to use for this broadcast","example":42},"templateId":{"type":"number","description":"WhatsApp template ID to use for this broadcast (required for WhatsApp channels)","example":486},"headerFooter":{"type":"object","description":"Header/Footer content (JSON array)","example":[{"type":"header","value":"Header Text"},{"type":"footer","value":"Footer Text"}]},"folderId":{"type":"number","description":"Object folder ID","example":1},"sendOverrides":{"description":"Per-broadcast overrides for the selected WhatsApp template. Required for MARKETING_CAROUSEL templates (one override per card with media and optional body parameters).","allOf":[{"$ref":"#/components/schemas/BroadcastSendOverridesDto"}]}},"required":["message"]},"BroadcastResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Broadcast ID","example":31670},"externalId":{"type":"string","description":"External ID","example":"Tzi7izLRHU"},"channelId":{"type":"number","description":"Channel ID this broadcast belongs to","example":664},"segmentId":{"type":"number","description":"Segment ID this broadcast is targeted to (null = all contacts)","example":123},"message":{"type":"string","description":"Broadcast message content","example":"Hello everyone! This is our latest update."},"headerFooter":{"type":"object","description":"Header/Footer content (JSON array)","example":[{"type":"header","value":"Header Text"},{"type":"footer","value":"Footer Text"}]},"broadcastType":{"type":"string","description":"Broadcast type","enum":["text","image","video","audio","document"],"example":"text"},"layoutType":{"type":"string","description":"Layout of the linked template. \"carousel\" templates store broadcastType \"text\" (media lives per card), so consumers use this to surface the carousel as the user-facing type instead of mislabeling it \"text\".","enum":["standard","carousel"],"example":"standard"},"sendStatus":{"description":"Send status","example":"draft","allOf":[{"$ref":"#/components/schemas/BroadcastSendStatus"}]},"approved":{"type":"boolean","description":"Broadcast approved status","example":true},"locked":{"type":"boolean","description":"Broadcast locked status (read-only)","example":false},"test":{"type":"boolean","description":"Test broadcast flag","example":false},"templateId":{"type":"number","description":"Template ID used for this broadcast","example":486},"fallbackTemplateId":{"type":"number","description":"Fallback template ID when broadcast fails","example":500},"sendOverrides":{"description":"Per-broadcast template send overrides (carousel card media/params). mediaUri is resolved to a browser-loadable absolute URL so the detail page preview matches exactly what gets sent.","allOf":[{"$ref":"#/components/schemas/BroadcastSendOverridesDto"}]},"fallbackSkipDuplicate":{"type":"boolean","description":"Skip duplicate messages for fallback template","example":false},"shortlinks":{"type":"boolean","description":"Short links tracking enabled","example":false},"optimizedSending":{"type":"boolean","description":"Optimized sending enabled (advanced sending mode)","example":false},"recipientsRecovery":{"type":"boolean","description":"Recipients recovery enabled","example":false},"statistics":{"type":"object","description":"Broadcast statistics"},"errorDescription":{"type":"string","description":"Error description if broadcast failed","example":null},"createdAt":{"type":"string","description":"Broadcast creation date (ISO 8601)","example":"2021-06-21T12:05:57.000Z"},"scheduledAt":{"type":"string","description":"Scheduled send time (ISO 8601)","example":null},"sentAt":{"type":"string","description":"Actual send time (ISO 8601)","example":null},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2021-06-21T12:05:57.000Z"},"expiresAt":{"type":"string","description":"Expiration date (ISO 8601)","example":null},"media":{"description":"Media attachment (image, video, audio, etc.)","allOf":[{"$ref":"#/components/schemas/MediaMediaResponseDto"}]},"hasAbTest":{"type":"boolean","description":"Whether this broadcast has an A/B test configured","example":false},"abTestId":{"type":"number","description":"A/B test ID if configured","example":1},"abTestStatus":{"type":"string","description":"A/B test status if configured","example":"draft"},"quality":{"description":"Quality score based on message engagement (read/received vs sent)","allOf":[{"$ref":"#/components/schemas/QualityDto"}]},"folderId":{"type":"number","description":"Object folder ID","example":1},"createdBy":{"type":"string","description":"Name of the user who created the broadcast","example":"Anna Schneider"}},"required":["id","externalId","channelId","message","broadcastType","sendStatus","approved","locked","test","fallbackSkipDuplicate","shortlinks","optimizedSending","recipientsRecovery","statistics","createdAt","updatedAt"]},"UpdateBroadcastDto":{"type":"object","properties":{"message":{"type":"string","description":"Broadcast message content","example":"Updated broadcast message"},"broadcastType":{"type":"string","description":"Broadcast type","enum":["text","image","video","audio","document"],"example":"text"},"scheduledAt":{"type":"number","description":"Unix timestamp when broadcast should be sent (0 or max int32 for unscheduled)","example":1699999999},"test":{"type":"boolean","description":"Test broadcast flag","example":false},"approved":{"type":"boolean","description":"Broadcast approved status","example":true},"locked":{"type":"boolean","description":"Broadcast locked status","example":false},"sendStatus":{"description":"Send status","example":"draft","allOf":[{"$ref":"#/components/schemas/BroadcastSendStatus"}]},"templateId":{"type":"number","description":"Template ID used for this broadcast","example":486},"segmentId":{"type":"object","description":"Target segment ID; null or 0 sends to all contacts","example":123,"nullable":true},"fallbackTemplateId":{"type":"number","description":"Fallback template ID when broadcast fails","example":500},"fallbackSkipDuplicate":{"type":"boolean","description":"Skip duplicate messages for fallback template","example":false},"shortlinks":{"type":"boolean","description":"Short links tracking enabled","example":false},"optimizedSending":{"type":"boolean","description":"Optimized sending enabled (advanced sending mode)","example":false},"recipientsRecovery":{"type":"boolean","description":"Recipients recovery enabled","example":false},"headerFooter":{"type":"object","description":"Header/Footer content (JSON array)","example":[{"type":"header","value":"Header Text"},{"type":"footer","value":"Footer Text"}]},"removeMedia":{"type":"boolean","description":"Remove existing media from broadcast","example":false},"libraryMediaId":{"type":"number","description":"Library media ID to attach (replaces existing media)","example":42},"mediaIds":{"description":"Uploaded media UUIDs (temp upload) to attach","example":["a1c339d3ecc70cb37d0052e21197ce33"],"type":"array","items":{"type":"string"}},"folderId":{"type":"number","description":"Object folder ID","example":1},"sendOverrides":{"description":"Per-broadcast carousel usage overrides (media + body parameters per card). Only editable while the broadcast is unsent; the template structure stays fixed.","allOf":[{"$ref":"#/components/schemas/BroadcastSendOverridesDto"}]}}},"ShortLinkResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Short link ID","example":1},"externalId":{"type":"string","description":"External ID (short code)","example":"aBc12345"},"originalUrl":{"type":"string","description":"Original/destination URL","example":"https://example.com/landing"},"shortUrl":{"type":"string","description":"Shortened URL","example":"https://short.instantkom.app/aBc12345"},"referenceType":{"type":"string","description":"Reference type","example":"b"},"referenceId":{"type":"number","description":"Reference ID","example":123},"clickCount":{"type":"number","description":"Total number of clicks","example":42},"numImpressions":{"type":"number","description":"Number of impressions (views)","example":150},"conversionRate":{"type":"number","description":"Conversion rate percentage (clicks / impressions * 100)","example":28},"recentClicks":{"type":"array","description":"Recent clicks with timestamps","items":{"type":"object"}},"createdAt":{"type":"object","description":"ISO 8601 creation timestamp","example":"2025-01-01T00:00:00.000Z"},"updatedAt":{"type":"object","description":"ISO 8601 last update timestamp","example":"2025-01-01T00:00:00.000Z"},"folderId":{"type":"object","description":"Object folder ID","example":1}},"required":["id","externalId","originalUrl","shortUrl","referenceType","referenceId","clickCount","numImpressions","conversionRate","recentClicks","createdAt","updatedAt","folderId"]},"CreateTagDto":{"type":"object","properties":{"name":{"type":"string","description":"Tag name","example":"VIP Customer","maxLength":100},"description":{"type":"string","description":"Tag description","example":"High-value customers with premium support","maxLength":2000},"color":{"type":"string","description":"Tag color (hex format)","example":"#3B82F6","default":"#3B82F6"},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["name"]},"TagResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Tag ID","example":1234},"name":{"type":"string","description":"Tag name","example":"VIP Customer"},"description":{"type":"string","description":"Tag description","example":"High-value customers with premium support"},"color":{"type":"string","description":"Tag color (hex format)","example":"#3B82F6"},"folderId":{"type":"number","description":"Folder ID for organization","example":null},"recipientCount":{"type":"number","description":"Number of recipients tagged","example":42},"segmentCount":{"type":"number","description":"Number of segments using this tag","example":3},"botCount":{"type":"number","description":"Number of bots using this tag","example":2}},"required":["id","name","color","recipientCount"]},"UpdateTagDto":{"type":"object","properties":{"name":{"type":"string","description":"Tag name","example":"VIP Customer","maxLength":100},"description":{"type":"string","description":"Tag description","example":"High-value customers with premium support","maxLength":2000},"color":{"type":"string","description":"Tag color (hex format)","example":"#3B82F6"},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"AssignTagsDto":{"type":"object","properties":{"recipientIds":{"description":"Array of recipient IDs to assign tags to","example":[123,456,789],"type":"array","items":{"type":"number"}}},"required":["recipientIds"]},"TagsRemoveTagsDto":{"type":"object","properties":{"recipientIds":{"description":"Array of recipient IDs to remove tags from","example":[123,456,789],"type":"array","items":{"type":"number"}}},"required":["recipientIds"]},"TagImportItemDto":{"type":"object","properties":{"name":{"type":"string","description":"Tag name","example":"VIP Customer"},"description":{"type":"string","description":"Tag description","example":"High-value customers"},"color":{"type":"string","description":"Tag color (hex format)","example":"#3B82F6"}},"required":["name"]},"TagsValidateImportDto":{"type":"object","properties":{"tags":{"description":"Array of tags to validate","type":"array","items":{"$ref":"#/components/schemas/TagImportItemDto"}}},"required":["tags"]},"ImportValidationErrorDto":{"type":"object","properties":{"row":{"type":"number","description":"Row number (1-indexed)","example":3},"field":{"type":"string","description":"Field that caused the error","example":"color"},"message":{"type":"string","description":"Error message","example":"Invalid hex color format"},"value":{"type":"string","description":"Invalid value","example":"red"}},"required":["row","field","message","value"]},"ValidateResultDto":{"type":"object","properties":{"valid":{"type":"boolean","description":"Whether all items are valid","example":true},"validCount":{"type":"number","description":"Number of valid items","example":18},"invalidCount":{"type":"number","description":"Number of invalid items","example":2},"duplicateCount":{"type":"number","description":"Number of duplicates that would be skipped","example":3},"errors":{"description":"Validation errors","type":"array","items":{"$ref":"#/components/schemas/ImportValidationErrorDto"}}},"required":["valid","validCount","invalidCount","duplicateCount","errors"]},"ImportTagsDto":{"type":"object","properties":{"tags":{"description":"Array of tags to import","type":"array","items":{"$ref":"#/components/schemas/TagImportItemDto"}},"skipDuplicates":{"type":"boolean","description":"Skip duplicate tag names instead of failing","default":true}},"required":["tags"]},"TagsImportResultDto":{"type":"object","properties":{"imported":{"type":"number","description":"Number of successfully imported items","example":15},"skipped":{"type":"number","description":"Number of skipped items (duplicates)","example":3},"failed":{"type":"number","description":"Number of failed items","example":2},"total":{"type":"number","description":"Total items processed","example":20},"errors":{"description":"Validation errors for failed items","type":"array","items":{"$ref":"#/components/schemas/ImportValidationErrorDto"}},"importedIds":{"description":"IDs of successfully imported tags","example":[101,102,103],"type":"array","items":{"type":"number"}}},"required":["imported","skipped","failed","total","errors","importedIds"]},"CarouselCardButtonDto":{"type":"object","properties":{"type":{"type":"string","description":"Button type","enum":["quick_reply","url"]},"text":{"type":"string","description":"Button text","example":"Buy Now"},"payload":{"type":"string","description":"Quick reply payload","example":"buy-a"},"url":{"type":"string","description":"URL for url-type buttons","example":"https://example.com"},"urlSuffix":{"type":"string","description":"Dynamic URL suffix","example":"product-a"}},"required":["type","text"]},"CarouselCardDto":{"type":"object","properties":{"mediaUrl":{"type":"string","description":"Media URL (HTTPS)","example":"https://example.com/image.jpg"},"mediaType":{"type":"string","description":"Media type","enum":["image","video"]},"libraryMediaId":{"type":"number","description":"Media library ID for reusable card media","example":42},"bodyText":{"type":"string","description":"Card body text (max 160 chars)","example":"Product A - Only 29 EUR!"},"bodyVariables":{"description":"Body text variables","example":["Product A","29 EUR"],"type":"array","items":{"type":"string"}},"buttons":{"description":"Card buttons (max 2)","type":"array","items":{"$ref":"#/components/schemas/CarouselCardButtonDto"}}},"required":["bodyText","buttons"]},"CreateTemplateDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID","example":123},"name":{"type":"string","description":"Template name","example":"Welcome Message","maxLength":200},"type":{"type":"string","description":"Template type","example":"text","enum":["text","image","video","document","audio","location","contact","interactive"]},"message":{"type":"string","description":"Template message content (required for standard, empty for carousel)","example":"Hello {{name}}!"},"color":{"type":"string","description":"Color code (hex)","example":"#FF5733"},"whatsappLanguage":{"type":"string","description":"WhatsApp template language code used for approval submission","example":"en"},"whatsappCategory":{"type":"number","description":"WhatsApp template category: 1=AUTHENTICATION, 2=UTILITY, 3=MARKETING (default)","example":3},"status":{"type":"boolean","description":"Active status","example":true},"isTest":{"type":"boolean","description":"Is test template","example":false},"folderId":{"type":"number","description":"Folder ID","example":1},"tagId":{"type":"number","description":"Tag ID","example":5},"buttons":{"type":"object","description":"Buttons content (JSON array)","example":[{"type":"quick_reply","text":"Yes"},{"type":"quick_reply","text":"No"}]},"headerFooter":{"type":"object","description":"Header/Footer content (JSON object)","example":{"header":"Header Text","footer":"Footer Text"}},"mediaIds":{"description":"Uploaded media UUIDs to attach to the template","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string"}},"libraryMediaId":{"type":"number","description":"Media library ID to link existing media","example":42},"ownerUserId":{"type":"object","description":"Owner user ID (team member assignment, -1 for no owner)","example":456},"autosendTimeOfDay":{"type":"string","description":"Auto-broadcast time of day (HH:MM format)","example":"08:00"},"autosendFrequency":{"type":"number","description":"Auto-broadcast frequency (0=daily, 1=weekly, 2=monthly, null=disabled)","example":1,"enum":[0,1,2]},"autosendDaysOfWeek":{"type":"string","description":"Auto-broadcast days of week (string of day numbers 0-6, e.g., \"12345\" for Mon-Fri)","example":"12345"},"autosendDaysOfMonth":{"type":"string","description":"Auto-broadcast days of month in bracket format (e.g., \"[1][15][31]\")","example":"[1][15]"},"autosendTargets":{"description":"Auto-broadcast target channels and segments","example":[{"channelId":505},{"channelId":506,"segmentId":123}],"type":"array","items":{"type":"string"}},"layoutType":{"type":"string","description":"Layout type (standard or carousel)","example":"standard","enum":["standard","carousel"]},"carouselCards":{"description":"Carousel card definitions (2-10 cards, for carousel templates only)","type":"array","items":{"$ref":"#/components/schemas/CarouselCardDto"}},"sampleValues":{"type":"object","description":"WhatsApp template variable example values (key=placeholder name, value=sample text)","example":{"1":"Max Mustermann","2":"Berlin"},"additionalProperties":{"type":"string"}}},"required":["channelId","name","type","message"]},"TemplateResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Internal ID","example":486},"externalId":{"type":"string","description":"External ID","example":"7Syxbjqw3c"},"name":{"type":"string","description":"Template name","example":"WAB Issue Resolution"},"type":{"type":"string","description":"Template type","example":"text"},"channelId":{"type":"number","description":"Channel ID","example":505},"message":{"type":"string","description":"Template message","example":"Hello {{name}}!"},"status":{"type":"boolean","description":"Active status","example":true},"color":{"type":"string","description":"Color code","example":"#FFFFFF"},"isTest":{"type":"boolean","description":"Is test template","example":false},"ownerUserId":{"type":"number","description":"Owner user ID","example":1098},"autosendTimeOfDay":{"type":"string","description":"Auto-send time of day (HH:MM format)","example":"14:30"},"autosendFrequency":{"type":"number","description":"Auto-send frequency (0=daily, 1=weekly, 2=monthly)","example":1},"autosendDaysOfWeek":{"type":"string","description":"Auto-send days of week (string of day numbers 0-6, e.g., \"12345\" for Mon-Fri)","example":"12345"},"autosendDaysOfMonth":{"type":"string","description":"Auto-send days of month in bracket format","example":"[1][15][31]"},"autosendTargets":{"description":"Auto-send target channels and segments","example":[{"channelId":505,"segmentId":0},{"channelId":506,"segmentId":123}],"type":"array","items":{"type":"string"}},"folderId":{"type":"number","description":"Folder ID","example":1},"tagId":{"type":"number","description":"Tag ID","example":5},"buttons":{"type":"object","description":"Buttons content (JSON array)"},"headerFooter":{"type":"object","description":"Header/Footer content (JSON object)"},"lastSentAt":{"type":"object","description":"Last sent timestamp (ISO 8601)","example":"2024-11-15T10:26:39.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2024-11-15T10:26:39.000Z"},"whatsappEnabled":{"type":"boolean","description":"Whether this is a WhatsApp Business API template (wab_sts)","example":true},"whatsappStatus":{"type":"number","description":"WhatsApp template approval status (0=not submitted, 10=active, 9=rejected)","example":10},"whatsappId":{"type":"string","description":"WhatsApp template internal ID/name","example":"order_confirmation_v1"},"whatsappNamespace":{"type":"string","description":"WhatsApp Business namespace","example":"a1b2c3d4_e5f6_g7h8_i9j0_k1l2m3n4o5p6"},"whatsappGuid":{"type":"string","description":"WhatsApp template GUID","example":"123456789012345"},"whatsappLanguage":{"type":"string","description":"WhatsApp template language code (de, en, es, etc.)","example":"de"},"whatsappCategory":{"type":"number","description":"WhatsApp template category (1=Authentication, 2=Utility, 3=Marketing)","example":3},"whatsappQualityScore":{"type":"string","description":"Effective WhatsApp template quality value (UNKNOWN, GREEN, YELLOW, or RED)","example":"GREEN"},"layoutType":{"type":"string","description":"Layout type (standard or carousel)","example":"standard","enum":["standard","carousel"]},"carouselCards":{"description":"Carousel card definitions (JSON array, for carousel templates only)","type":"array","items":{"type":"string"}},"sampleValues":{"type":"object","description":"WhatsApp template variable example values (key=placeholder name, value=sample text)","example":{"1":"Max Mustermann","2":"Berlin"},"additionalProperties":{"type":"string"}},"undeletable":{"type":"boolean","description":"Cannot be deleted","example":false},"createdAt":{"type":"string","description":"Creation timestamp (ISO 8601)","example":"2024-01-10T08:15:00.000Z"},"media":{"description":"Media attachment information (if template has media)","allOf":[{"$ref":"#/components/schemas/TemplateMediaDto"}]}},"required":["id","externalId","name","type","channelId","message","status","color","isTest","updatedAt","undeletable","createdAt"]},"UpdateTemplateDto":{"type":"object","properties":{"name":{"type":"string","description":"Template name","example":"Welcome Message","maxLength":200},"type":{"type":"string","description":"Template type","example":"text","enum":["text","image","video","document","audio","location","contact","interactive"]},"message":{"type":"string","description":"Template message content (required for standard, empty for carousel)","example":"Hello {{name}}!"},"color":{"type":"string","description":"Color code (hex)","example":"#FF5733"},"whatsappLanguage":{"type":"string","description":"WhatsApp template language code used for approval submission","example":"en"},"whatsappCategory":{"type":"number","description":"WhatsApp template category: 1=AUTHENTICATION, 2=UTILITY, 3=MARKETING (default)","example":3},"status":{"type":"boolean","description":"Active status","example":true},"isTest":{"type":"boolean","description":"Is test template","example":false},"folderId":{"type":"number","description":"Folder ID","example":1},"tagId":{"type":"number","description":"Tag ID","example":5},"buttons":{"type":"object","description":"Buttons content (JSON array)","example":[{"type":"quick_reply","text":"Yes"},{"type":"quick_reply","text":"No"}]},"headerFooter":{"type":"object","description":"Header/Footer content (JSON object)","example":{"header":"Header Text","footer":"Footer Text"}},"mediaIds":{"description":"Uploaded media UUIDs to attach to the template","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string"}},"libraryMediaId":{"type":"number","description":"Media library ID to link existing media","example":42},"ownerUserId":{"type":"object","description":"Owner user ID (team member assignment, -1 for no owner)","example":456},"autosendTimeOfDay":{"type":"string","description":"Auto-broadcast time of day (HH:MM format)","example":"08:00"},"autosendFrequency":{"type":"number","description":"Auto-broadcast frequency (0=daily, 1=weekly, 2=monthly, null=disabled)","example":1,"enum":[0,1,2]},"autosendDaysOfWeek":{"type":"string","description":"Auto-broadcast days of week (string of day numbers 0-6, e.g., \"12345\" for Mon-Fri)","example":"12345"},"autosendDaysOfMonth":{"type":"string","description":"Auto-broadcast days of month in bracket format (e.g., \"[1][15][31]\")","example":"[1][15]"},"autosendTargets":{"description":"Auto-broadcast target channels and segments","example":[{"channelId":505},{"channelId":506,"segmentId":123}],"type":"array","items":{"type":"string"}},"layoutType":{"type":"string","description":"Layout type (standard or carousel)","example":"standard","enum":["standard","carousel"]},"carouselCards":{"description":"Carousel card definitions (2-10 cards, for carousel templates only)","type":"array","items":{"$ref":"#/components/schemas/CarouselCardDto"}},"sampleValues":{"type":"object","description":"WhatsApp template variable example values (key=placeholder name, value=sample text)","example":{"1":"Max Mustermann","2":"Berlin"},"additionalProperties":{"type":"string"}},"removeMedia":{"type":"boolean","description":"Remove existing media attachment from the template","example":true}}},"TemplateImportItemDto":{"type":"object","properties":{"name":{"type":"string","description":"Template name","example":"Welcome Message"},"type":{"type":"string","description":"Template type (text, image, video, audio, document)","example":"text"},"message":{"type":"string","description":"Message content","example":"Hello {{name}}, welcome to our service!"},"color":{"type":"string","description":"Template color (hex format)","example":"#FFFFFF"},"status":{"type":"boolean","description":"Template status (active/inactive)","example":true},"isTest":{"type":"boolean","description":"Is test template","example":false},"buttons":{"type":"object","description":"Buttons configuration as JSON"},"headerFooter":{"type":"object","description":"Header/Footer configuration as JSON"}},"required":["name","type","message"]},"TemplatesValidateImportDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID to validate against","example":123},"templates":{"description":"Array of templates to validate","type":"array","items":{"$ref":"#/components/schemas/TemplateImportItemDto"}}},"required":["channelId","templates"]},"ImportTemplatesDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID to import templates into","example":123},"templates":{"description":"Array of templates to import","type":"array","items":{"$ref":"#/components/schemas/TemplateImportItemDto"}},"skipDuplicates":{"type":"boolean","description":"Skip duplicate template names instead of failing","default":true}},"required":["channelId","templates"]},"TemplatesImportResultDto":{"type":"object","properties":{"imported":{"type":"number","description":"Number of successfully imported items","example":15},"skipped":{"type":"number","description":"Number of skipped items (duplicates)","example":3},"failed":{"type":"number","description":"Number of failed items","example":2},"total":{"type":"number","description":"Total items processed","example":20},"errors":{"description":"Validation errors for failed items","type":"array","items":{"$ref":"#/components/schemas/ImportValidationErrorDto"}},"importedIds":{"description":"IDs of successfully imported templates","example":[101,102,103],"type":"array","items":{"type":"number"}}},"required":["imported","skipped","failed","total","errors","importedIds"]},"CreateQrCodeDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID","example":123},"name":{"type":"string","description":"QR Code name","example":"Event Registration QR","maxLength":250},"description":{"type":"string","description":"Description","example":"QR code for event registration"},"size":{"type":"number","description":"QR Code size in pixels","example":512,"minimum":64,"maximum":2048},"includeLogo":{"type":"boolean","description":"Include logo in QR code","example":false},"threemaCompatibility":{"type":"boolean","description":"Enable Threema-compatible QR code output for Threema channels","example":false},"foregroundColor":{"type":"string","description":"Foreground color (hex)","example":"#000000"},"backgroundColor":{"type":"string","description":"Background color (hex)","example":"#FFFFFF"},"keyword":{"type":"string","description":"Tracking keyword","example":"summer-event-2024"},"enableTracking":{"type":"boolean","description":"Enable tracking","example":true},"folderId":{"type":"number","description":"Folder ID","example":1},"status":{"type":"boolean","description":"Active status","example":true}},"required":["channelId","name"]},"QrCodeScanDto":{"type":"object","properties":{"ip":{"type":"string","description":"IP address of the scanner","example":"192.168.1.1"},"timestamp":{"type":"number","description":"Unix timestamp of the scan","example":1700000000},"countryCode":{"type":"object","description":"ISO 3166-1 alpha-2 country code","example":"DE"},"countryName":{"type":"object","description":"Full country name","example":"Germany"},"city":{"type":"object","description":"City name","example":"Berlin"}},"required":["ip","timestamp"]},"QrCodeResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Internal ID","example":1},"externalId":{"type":"string","description":"External ID","example":"ssga5P4ifi"},"embedId":{"type":"string","description":"Clean embed ID for /public/embed/qr routes","example":"abc123def456"},"name":{"type":"string","description":"QR Code name","example":"Event Registration QR"},"description":{"type":"string","description":"Description","example":"QR code for event registration"},"channelId":{"type":"number","description":"Channel ID","example":505},"status":{"type":"boolean","description":"Active status","example":true},"size":{"type":"number","description":"QR Code size in pixels","example":512},"includeLogo":{"type":"boolean","description":"Include logo","example":false},"threemaCompatibility":{"type":"boolean","description":"Threema-compatible QR output enabled","example":false},"foregroundColor":{"type":"string","description":"Foreground color","example":"#000000"},"backgroundColor":{"type":"string","description":"Background color","example":"#FFFFFF"},"keyword":{"type":"string","description":"Tracking keyword","example":"summer-event-2024"},"enableTracking":{"type":"boolean","description":"Tracking enabled","example":true},"leads":{"type":"number","description":"Number of leads","example":0},"leadsReal":{"type":"number","description":"Number of real leads","example":0},"impressions":{"type":"number","description":"Number of impressions","example":2},"scanRate":{"type":"number","description":"Scan rate as decimal (0-1) - leads / impressions","example":0.425},"conversionRate":{"type":"number","description":"Conversion rate as decimal (0-1) - real leads / leads","example":0.75},"folderId":{"type":"object","description":"Folder ID","example":1},"createdAt":{"type":"object","description":"Creation timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"updatedAt":{"type":"object","description":"Last update timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"recentScans":{"description":"Recent scans (only included in single-item responses)","type":"array","items":{"$ref":"#/components/schemas/QrCodeScanDto"}}},"required":["id","externalId","embedId","name","description","channelId","status","size","includeLogo","threemaCompatibility","foregroundColor","backgroundColor","keyword","enableTracking","leads","leadsReal","impressions","scanRate","conversionRate","folderId","createdAt","updatedAt","recentScans"]},"UpdateQrCodeDto":{"type":"object","properties":{"name":{"type":"string","description":"QR Code name","example":"Event Registration QR","maxLength":250},"description":{"type":"string","description":"Description","example":"QR code for event registration"},"size":{"type":"number","description":"QR Code size in pixels","example":512,"minimum":64,"maximum":2048},"includeLogo":{"type":"boolean","description":"Include logo in QR code","example":false},"threemaCompatibility":{"type":"boolean","description":"Enable Threema-compatible QR code output for Threema channels","example":false},"foregroundColor":{"type":"string","description":"Foreground color (hex)","example":"#000000"},"backgroundColor":{"type":"string","description":"Background color (hex)","example":"#FFFFFF"},"keyword":{"type":"string","description":"Tracking keyword","example":"summer-event-2024"},"enableTracking":{"type":"boolean","description":"Enable tracking","example":true},"folderId":{"type":"number","description":"Folder ID","example":1},"status":{"type":"boolean","description":"Active status","example":true}}},"ChatResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Chat ID","example":1},"recipientId":{"type":"number","description":"Recipient ID","example":123},"recipientName":{"type":"string","description":"Recipient name","example":"John Doe"},"recipientPhone":{"type":"string","description":"Recipient phone number","example":"+491234567890"},"recipientNickname":{"type":"string","description":"Recipient nickname","example":"Johnny"},"channelId":{"type":"number","description":"Channel ID","example":5},"channelName":{"type":"string","description":"Channel name","example":"WhatsApp Business"},"gatewayType":{"type":"string","description":"Channel gateway type","example":"whatsapp"},"unread":{"type":"number","description":"Number of unread messages","example":3},"totalMessages":{"type":"number","description":"Total number of messages in chat","example":42},"lastMessage":{"type":"string","description":"Last message preview","example":"Hello, how can I help?"},"lastMessageType":{"type":"string","description":"Last message type","example":"text"},"lastMessageDirection":{"type":"string","description":"Last message direction","example":"received","enum":["sent","received"]},"lastMessageAt":{"type":"object","description":"Last message timestamp (ISO 8601)","example":"2023-11-13T10:29:03.000Z"},"unreadSince":{"type":"string","description":"Timestamp of last unread message (ISO 8601)","example":"2023-11-13T10:29:03.000Z"},"archived":{"type":"boolean","description":"Whether the chat is archived","example":false},"processed":{"type":"boolean","description":"Whether the chat is marked as processed (handled)","example":false},"starred":{"type":"boolean","description":"Whether the chat is starred for priority","example":false},"chatWindow":{"description":"WhatsApp 24h chat window status (only for WhatsApp channels)","allOf":[{"$ref":"#/components/schemas/ChatWindowDto"}]},"hasAvatar":{"type":"boolean","description":"Whether the recipient has a profile picture on file","example":false},"createdAt":{"type":"string","description":"Chat created at (ISO 8601)","example":"2023-11-12T06:35:43.000Z"}},"required":["id","recipientId","unread","totalMessages","unreadSince","archived","processed","starred","hasAvatar","createdAt"]},"SendMessageDto":{"type":"object","properties":{"text":{"type":"string","description":"Message text (plain text; rendered safely, never executed as HTML)"},"idempotencyKey":{"type":"string","description":"Client-generated idempotency key to make retries safe (no duplicate persistence)"}},"required":["text"]},"CreateBotDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID this bot belongs to","example":5},"name":{"type":"string","description":"Bot name","example":"Welcome Bot","maxLength":80},"type":{"type":"string","description":"Bot type","example":"keyword","enum":["keyword","schedule","event","ai"]},"message":{"type":"string","description":"Message content. Required for all bot types except \"ai\", where the reply is produced by the linked AI prompt and the message may be empty.","example":"Hello! How can I help you?"},"color":{"type":"string","description":"Color for bot identification","example":"#3498DB","default":"#3498DB"},"contentButtons":{"type":"object","description":"WhatsApp buttons (JSON array)","example":[]},"contentHeaderFooter":{"type":"object","description":"WhatsApp header/footer (JSON object)","example":{}},"thresholdMinutes":{"type":"number","description":"Threshold in minutes between bot activations","example":60,"default":0},"skipCommands":{"type":"boolean","description":"Skip bot if message contains commands","example":true,"default":false},"allowDuplicateMessages":{"type":"boolean","description":"Allow bot to trigger on duplicate messages","example":false,"default":false},"tags":{"type":"string","description":"Tags to assign (comma-separated)","example":"customer,support"},"folderId":{"type":"number","description":"Folder ID for organization","example":1},"botReplyMediaId":{"type":"object","description":"Library media ID for bot reply media (image or video)","example":42,"nullable":true}},"required":["channelId","name","type","message"]},"BotFilterObject":{"type":"string","enum":["msg","recipient","ecom_order","ecom_cart","ecom_customer"],"description":"Object type to filter on"},"BotFilterResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Filter ID","example":1},"botId":{"type":"number","description":"Bot ID","example":42},"name":{"type":"string","description":"Filter name","example":"VIP Customer Filter"},"description":{"type":"string","description":"Filter description"},"color":{"type":"string","description":"Display color (hex)","example":"#FF5733"},"status":{"type":"number","description":"Status (0=inactive, 1=active)","example":1},"operator":{"description":"Logical operator for filter conditions","example":"and","allOf":[{"$ref":"#/components/schemas/BotFilterOperator"}]},"operatorGroup":{"type":"number","description":"Operator group for complex logic","example":0},"objectType":{"description":"Object type to filter on","example":"msg","allOf":[{"$ref":"#/components/schemas/BotFilterObject"}]},"attribute":{"description":"Attribute to check","example":"text","allOf":[{"$ref":"#/components/schemas/BotFilterAttribute"}]},"comparator":{"description":"Comparison operator","example":"contains","allOf":[{"$ref":"#/components/schemas/BotFilterComparator"}]},"value":{"type":"string","description":"Value to compare against","example":"hello"},"conditionObjectType":{"description":"Semantic object type for legacy-compatible filter restoration. Use this instead of objectType for modern builders.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionObjectType"}]},"conditionAttribute":{"description":"Semantic condition attribute derived from legacy objtype/attr combinations.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionAttribute"}]},"conditionComparator":{"description":"Semantic comparator derived from legacy cmp codes and the condition family.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionComparator"}]},"conditionEnvVarId":{"type":"number","description":"Bot env var ID when conditionObjectType=environment_variable.","example":17},"valueEditor":{"description":"Preferred editor family for this condition in the frontend.","allOf":[{"$ref":"#/components/schemas/BotFilterValueEditor"}]},"legacyObjectTypeCode":{"type":"number","description":"Raw legacy objtype code for migration/debugging.","example":3},"legacyAttributeCode":{"type":"number","description":"Raw legacy attr code for migration/debugging.","example":42},"legacyComparatorCode":{"type":"number","description":"Raw legacy cmp code for migration/debugging.","example":2},"testCount":{"type":"number","description":"Number of test executions","example":150},"matchCount":{"type":"number","description":"Number of successful matches","example":42},"matchRate":{"type":"number","description":"Match rate (matchCount / testCount)","example":0.28}},"required":["id","botId","name","status","operator","operatorGroup","objectType","attribute","comparator","value","testCount","matchCount"]},"BotResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Bot ID","example":1},"externalId":{"type":"string","description":"External ID","example":"aBc1234567"},"name":{"type":"string","description":"Bot name","example":"Welcome Bot"},"status":{"type":"boolean","description":"Active status","example":true},"type":{"type":"string","description":"Bot type","example":"keyword","enum":["keyword","schedule","event","ai"]},"channelId":{"type":"number","description":"Channel ID","example":5},"color":{"type":"string","description":"Color for bot identification","example":"#3498db"},"message":{"type":"string","description":"Message content","example":"Hello! How can I help you?"},"contentButtons":{"type":"object","description":"WhatsApp buttons (JSON array)","example":[]},"contentHeaderFooter":{"type":"object","description":"WhatsApp header/footer (JSON object)","example":{}},"createdAt":{"type":"object","description":"Creation timestamp (ISO 8601)","example":"2024-11-13T08:15:43.000Z","nullable":true},"lastRunAt":{"type":"object","description":"Last run timestamp (ISO 8601)","example":"2024-11-13T08:15:43.000Z"},"testRuns":{"type":"number","description":"Total number of test runs","example":42},"thresholdMinutes":{"type":"number","description":"Threshold in minutes between bot activations","example":60},"skipCommands":{"type":"boolean","description":"Skip bot if message contains commands","example":false},"allowDuplicateMessages":{"type":"boolean","description":"Allow bot to trigger on duplicate messages","example":false},"tags":{"type":"string","description":"Tags to assign (comma-separated)","example":"customer,support"},"folderId":{"type":"number","description":"Folder ID for organization","example":1},"filters":{"description":"Filter conditions","type":"array","items":{"$ref":"#/components/schemas/BotFilterResponseDto"}},"recipientSubscriptionAction":{"type":"boolean","description":"Trigger recipient subscription action when bot matches","example":false},"recipientSubscriptionActionChannelId":{"type":"number","description":"Subscription action: target channel ID","example":505},"recipientSubscriptionActionSegmentationId":{"type":"number","description":"Subscription action: target segmentation ID","example":10},"recipientSubscriptionActionState":{"type":"number","description":"Subscription action: state (subscribe/unsubscribe)","example":1},"recipientSubscriptionActionSilent":{"type":"boolean","description":"Subscription action: execute silently without notification","example":false},"environmentStatus":{"type":"boolean","description":"Environment variables enabled for this bot","example":false},"environmentKey":{"type":"string","description":"Environment variable key","example":"USER_NAME"},"environmentValue":{"type":"string","description":"Environment variable value","example":"John Doe"},"hliInteractionId":{"type":"number","description":"HLI interaction ID for advanced interactions","example":5},"sendOutstandingBroadcasts":{"type":"boolean","description":"Send outstanding broadcasts when bot matches","example":false},"aiPromptId":{"type":"number","description":"AI prompt ID for AI-powered bot responses","example":3},"fallbackTemplateId":{"type":"number","description":"Fallback template ID when bot fails","example":42},"fallbackTemplateBodyParams":{"description":"WhatsApp template body parameter values for the fallback template, in order of {{1}}, {{2}}, ...","example":["first name","renewal date"],"type":"array","items":{"type":"string"}},"fallbackTemplateSendOverrides":{"description":"Per-card carousel usage overrides for the fallback template. Uses the same contract as broadcast sendOverrides.","allOf":[{"$ref":"#/components/schemas/BroadcastSendOverridesDto"}]},"activeDateStatus":{"type":"boolean","description":"Time-based activation enabled","example":false},"activeDateStart":{"type":"string","description":"Activity period start date (ISO 8601)","example":"2025-01-01T00:00:00.000Z"},"activeDateEnd":{"type":"string","description":"Activity period end date (ISO 8601)","example":"2025-12-31T23:59:59.000Z"},"allowedMatches":{"type":"number","description":"Number of allowed matches before bot becomes inactive","example":1},"autotagEnabled":{"type":"boolean","description":"Smart auto-tagging enabled","example":false},"autotagTarget":{"type":"number","description":"Auto-tag target (0=recipient, 1=message)","example":0},"autotagQuantity":{"type":"number","description":"Auto-tag quantity (0=all tags, 1=matching tag only)","example":0},"autotagMode":{"type":"number","description":"Auto-tag mode (0=keyword, 1=llm) - used when quantity=1","example":0},"autotagKeywords":{"type":"string","description":"Keyword-to-tag mapping (JSON)","example":"{\"1\": [\"hello\", \"hi\"]}"},"escalationEnabled":{"type":"boolean","description":"Enable escalation-keyword handoff to a human (Issue #4915)","example":true},"escalationKeywords":{"type":"string","description":"Escalation keywords that trigger human handoff (flat JSON array)","example":"[\"Mitarbeiter\", \"Beschwerde\", \"kuendigen\"]"},"autotagFallbackTagId":{"type":"number","description":"Fallback tag ID when no match","example":0},"ticketCreateEnabled":{"type":"boolean","description":"Automatic ticket creation enabled","example":false},"ticketCreatePriority":{"type":"number","description":"Ticket priority (0=low, 1=normal, 2=high, 3=urgent)","example":1},"ticketCreateRoutingMode":{"type":"number","description":"Ticket routing mode (0=none, 1=tag_based, 2=fixed)","example":0},"ticketCreateFixedUserId":{"type":"number","description":"Fixed user ID for ticket assignment","example":0},"ticketCreateDistributionStrategy":{"type":"string","description":"Distribution strategy for tag-based routing (first, round_robin, least_tickets)","example":"first"},"ticketCreateSubjectMode":{"type":"number","description":"Ticket subject mode (0=auto, 1=custom)","example":0},"ticketCreateSubjectText":{"type":"string","description":"Custom ticket subject text","example":"Customer inquiry"},"quality":{"description":"Quality score based on bot matches vs tests","allOf":[{"$ref":"#/components/schemas/QualityDto"}]},"lastMatchAt":{"type":"object","description":"Timestamp of the last match (ISO 8601)","example":"2024-11-13T08:15:43.000Z"},"uniqueRecipientsCount":{"type":"number","description":"Number of unique recipients that triggered this bot","example":42},"totalMatchesCount":{"type":"number","description":"Total number of matches recorded","example":150},"matchesLast7Days":{"type":"number","description":"Number of matches in the last 7 days","example":25},"matchesLast30Days":{"type":"number","description":"Number of matches in the last 30 days","example":85},"matchesByDay":{"description":"Daily match counts for the last 30 days (array of {date, count})","example":[{"date":"2024-12-01","count":5},{"date":"2024-12-02","count":8}],"type":"array","items":{"type":"string"}},"msgMediaId":{"type":"object","description":"Library media ID of the stored bot reply media (image or video)","example":42,"nullable":true},"msgMediaMimeType":{"type":"object","description":"MIME type of the stored bot reply media; needed to render the attachment on load","example":"image/jpeg","nullable":true}},"required":["id","externalId","name","status","type","channelId","color","message","testRuns","thresholdMinutes","skipCommands","allowDuplicateMessages","recipientSubscriptionAction","recipientSubscriptionActionSilent","environmentStatus","sendOutstandingBroadcasts","activeDateStatus","allowedMatches","autotagEnabled","autotagTarget","autotagQuantity","ticketCreateEnabled"]},"UpdateBotDto":{"type":"object","properties":{"name":{"type":"string","description":"Bot name","example":"Updated Bot Name"},"status":{"type":"boolean","description":"Active status","example":true},"type":{"type":"string","description":"Bot type","example":"keyword","enum":["keyword","schedule","event","ai"]},"message":{"type":"string","description":"Message content","example":"Hello! How can I help you?"},"color":{"type":"string","description":"Color for bot identification","example":"#FF5733"},"contentButtons":{"type":"object","description":"WhatsApp buttons (JSON array)","example":[]},"contentHeaderFooter":{"type":"object","description":"WhatsApp header/footer (JSON object)","example":{}},"thresholdMinutes":{"type":"number","description":"Threshold in minutes between bot activations","example":60},"skipCommands":{"type":"boolean","description":"Skip bot if message contains commands","example":true},"allowDuplicateMessages":{"type":"boolean","description":"Allow bot to trigger on duplicate messages","example":false},"tags":{"type":"string","description":"Tags to assign (comma-separated)","example":"customer,support"},"folderId":{"type":"number","description":"Folder ID for organization","example":1},"aiPromptId":{"type":"number","description":"AI Prompt ID for AI-powered responses (0 to remove)","example":3},"recipientSubscriptionAction":{"type":"boolean","description":"Enable recipient subscription action when bot matches","example":false},"recipientSubscriptionActionChannelId":{"type":"number","description":"Subscription action: target channel ID","example":505},"recipientSubscriptionActionSegmentationId":{"type":"number","description":"Subscription action: target segmentation ID","example":10},"recipientSubscriptionActionState":{"type":"number","description":"Subscription action: state (0=unsubscribe, 1=subscribe)","example":1},"recipientSubscriptionActionSilent":{"type":"boolean","description":"Subscription action: execute silently without notification","example":false},"environmentStatus":{"type":"boolean","description":"Enable environment variables for this bot","example":false},"environmentKey":{"type":"string","description":"Environment variable key","example":"USER_NAME"},"environmentValue":{"type":"string","description":"Environment variable value","example":"John Doe"},"hliInteractionId":{"type":"number","description":"HLI interaction ID for advanced interactions (0 to remove)","example":5},"sendOutstandingBroadcasts":{"type":"boolean","description":"Send outstanding broadcasts when bot matches","example":false},"fallbackTemplateId":{"type":"number","description":"Fallback template ID when outside 24h window (0 to remove)","example":42,"nullable":true},"fallbackTemplateBodyParams":{"description":"WhatsApp template body parameter values for the fallback template, in order of {{1}}, {{2}}, ...","example":["first name","renewal date"],"nullable":true,"type":"array","items":{"type":"string"}},"fallbackTemplateSendOverrides":{"description":"Per-card carousel usage overrides for the fallback template. Uses the same contract as broadcast sendOverrides.","nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/BroadcastSendOverridesDto"}]},"activeDateStatus":{"type":"boolean","description":"Enable time-based activation","example":false},"activeDateStart":{"type":"string","description":"Activity period start date (ISO 8601)","example":"2025-01-01T00:00:00.000Z"},"activeDateEnd":{"type":"string","description":"Activity period end date (ISO 8601)","example":"2025-12-31T23:59:59.000Z"},"allowedMatches":{"type":"number","description":"Number of allowed matches before bot becomes inactive","example":1},"autotagEnabled":{"type":"boolean","description":"Enable smart auto-tagging","example":false},"autotagTarget":{"type":"number","description":"Auto-tag target (0=recipient, 1=message)","example":0},"autotagQuantity":{"type":"number","description":"Auto-tag quantity (0=all, 1=matching)","example":0},"autotagMode":{"type":"number","description":"Auto-tag mode (0=keyword, 1=llm) - used when quantity=1","example":0},"autotagKeywords":{"type":"string","description":"Keyword-to-tag mapping (JSON)","example":"{\"1\": [\"hello\", \"hi\"]}"},"escalationEnabled":{"type":"boolean","description":"Enable escalation-keyword handoff to a human (Issue #4915)","example":true},"escalationKeywords":{"type":"string","description":"Escalation keywords that trigger human handoff (flat JSON array)","example":"[\"Mitarbeiter\", \"Beschwerde\", \"kuendigen\"]"},"autotagFallbackTagId":{"type":"number","description":"Fallback tag ID when no match","example":0},"ticketCreateEnabled":{"type":"boolean","description":"Enable ticket creation","example":false},"ticketCreatePriority":{"type":"number","description":"Ticket priority (0=low, 1=normal, 2=high, 3=urgent)","example":1},"ticketCreateRoutingMode":{"type":"number","description":"Ticket routing mode (0=none, 1=tag_based, 2=fixed)","example":0},"ticketCreateFixedUserId":{"type":"number","description":"Fixed user ID for ticket assignment","example":0},"ticketCreateDistributionStrategy":{"type":"string","description":"Distribution strategy for tag-based routing (first, round_robin, least_tickets)","example":"first"},"ticketCreateSubjectMode":{"type":"number","description":"Ticket subject mode (0=auto, 1=custom)","example":0},"ticketCreateSubjectText":{"type":"string","description":"Custom ticket subject text","example":"Customer inquiry"},"botReplyMediaId":{"type":"object","description":"Library media ID for bot reply media (image/video/document/audio); null removes existing media","example":42,"nullable":true}}},"BotTagAssignmentResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Tag assignment ID","example":456},"tagId":{"type":"number","description":"Tag ID","example":123},"botId":{"type":"number","description":"Bot ID","example":789},"name":{"type":"string","description":"Tag name","example":"VIP Customer"},"color":{"type":"string","description":"Tag color (hex)","example":"#FF5733"},"assignedAt":{"type":"string","description":"Assignment timestamp (ISO 8601)","example":"2024-01-15T10:30:00.000Z"}},"required":["id","tagId","botId","name","color"]},"CreateBotFilterDto":{"type":"object","properties":{"name":{"type":"string","description":"Filter name","example":"VIP Customer Filter","maxLength":100},"description":{"type":"string","description":"Filter description"},"color":{"type":"string","description":"Display color (hex)","example":"#FF5733"},"status":{"type":"number","description":"Status (0=inactive, 1=active)","example":1},"operator":{"description":"Logical operator for filter conditions","example":"and","allOf":[{"$ref":"#/components/schemas/BotFilterOperator"}]},"operatorGroup":{"type":"number","description":"Operator group for complex logic","example":0},"objectType":{"description":"Object type to filter on","example":"msg","allOf":[{"$ref":"#/components/schemas/BotFilterObject"}]},"attribute":{"description":"Attribute to check","example":"text","allOf":[{"$ref":"#/components/schemas/BotFilterAttribute"}]},"comparator":{"description":"Comparison operator","example":"contains","allOf":[{"$ref":"#/components/schemas/BotFilterComparator"}]},"value":{"type":"string","description":"Value to compare against","example":"hello"},"conditionObjectType":{"description":"Semantic object type for the future condition builder. If set, the condition* fields are used instead of objectType/attribute/comparator.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionObjectType"}]},"conditionAttribute":{"description":"Semantic condition attribute for the future condition builder.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionAttribute"}]},"conditionComparator":{"description":"Semantic comparator for the future condition builder.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionComparator"}]},"conditionEnvVarId":{"type":"number","description":"Bot env var ID when conditionObjectType=environment_variable.","example":17}},"required":["name","operator","value"]},"UpdateBotFilterDto":{"type":"object","properties":{"name":{"type":"string","description":"Filter name","example":"VIP Customer Filter","maxLength":100},"description":{"type":"string","description":"Filter description"},"color":{"type":"string","description":"Display color (hex)","example":"#FF5733"},"status":{"type":"number","description":"Status (0=inactive, 1=active)","example":1},"operator":{"description":"Logical operator for filter conditions","example":"and","allOf":[{"$ref":"#/components/schemas/BotFilterOperator"}]},"operatorGroup":{"type":"number","description":"Operator group for complex logic","example":0},"objectType":{"description":"Object type to filter on","example":"msg","allOf":[{"$ref":"#/components/schemas/BotFilterObject"}]},"attribute":{"description":"Attribute to check","example":"text","allOf":[{"$ref":"#/components/schemas/BotFilterAttribute"}]},"comparator":{"description":"Comparison operator","example":"contains","allOf":[{"$ref":"#/components/schemas/BotFilterComparator"}]},"value":{"type":"string","description":"Value to compare against","example":"hello"},"conditionObjectType":{"description":"Semantic object type for the future condition builder. If set, the condition* fields are used instead of objectType/attribute/comparator.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionObjectType"}]},"conditionAttribute":{"description":"Semantic condition attribute for the future condition builder.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionAttribute"}]},"conditionComparator":{"description":"Semantic comparator for the future condition builder.","allOf":[{"$ref":"#/components/schemas/BotFilterConditionComparator"}]},"conditionEnvVarId":{"type":"number","description":"Bot env var ID when conditionObjectType=environment_variable.","example":17}}},"CreateSegmentationDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID this segmentation belongs to","example":5},"name":{"type":"string","description":"Segmentation name","example":"VIP Customers"},"description":{"type":"string","description":"Description","example":"High-value customers with frequent purchases"},"color":{"type":"string","description":"Color for visual identification","example":"#FF5733","default":"#3498db"},"tags":{"type":"string","description":"Tags for filtering recipients (comma-separated)","example":"vip,premium"},"enableOptInOut":{"type":"boolean","description":"Enable opt-in/out functionality","example":true,"default":false},"optInOutTagId":{"type":"number","description":"Assigned target tag for opt-in/out automation","example":42,"default":0},"optInCommands":{"type":"string","description":"Opt-in commands (comma-separated)","example":"JOIN,START"},"optInMessage":{"type":"string","description":"Opt-in message","example":"You have successfully joined our VIP list!"},"optOutMessage":{"type":"string","description":"Opt-out message","example":"You have been removed from our VIP list."},"autoOptoutStatus":{"type":"number","description":"Auto opt-out status","example":1,"default":0},"autoOptoutReoptin":{"type":"number","description":"Allowed number of self-service re-opt-ins (-1 = never, 0 = always)","example":0,"default":0},"autoOptoutDuration":{"type":"string","description":"Auto opt-out duration configuration (JSON)","example":"{\"mins\":0,\"hours\":0,\"days\":30,\"years\":0}"},"autoOptoutMessage":{"type":"string","description":"Message sent when a recipient is automatically opted out","example":"You have been automatically removed from this target group."},"autoOptoutDeclineMessage":{"type":"string","description":"Message sent when a re-opt-in is no longer allowed","example":"A renewed self-service registration is no longer allowed for this target group."},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["channelId","name"]},"SegmentationResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Segmentation ID","example":1},"externalId":{"type":"string","description":"External ID","example":"aBc1234567"},"name":{"type":"string","description":"Segmentation name","example":"VIP Customers"},"description":{"type":"string","description":"Description","example":"High-value customers"},"channelId":{"type":"number","description":"Channel ID","example":5},"color":{"type":"string","description":"Color for visual identification","example":"#3498db"},"tags":{"type":"string","description":"Tags for filtering recipients (comma-separated)","example":"vip,premium"},"recipientCount":{"type":"number","description":"Number of recipients in this segmentation","example":150},"optInOutEnabled":{"type":"boolean","description":"Opt-in/out enabled","example":false},"optInOutTagId":{"type":"object","description":"Assigned target tag for opt-in/out automation","example":42,"nullable":true},"optInCommands":{"type":"string","description":"Opt-in commands (comma-separated)","example":"JOIN,START"},"optInMessage":{"type":"string","description":"Opt-in message","example":"You have successfully joined!"},"optOutMessage":{"type":"string","description":"Opt-out message","example":"You have been removed."},"autoOptoutStatus":{"type":"number","description":"Auto opt-out status (0 = disabled, 1+ = enabled with specific mode)","example":0},"autoOptoutReoptin":{"type":"number","description":"Allowed number of self-service re-opt-ins (-1 = never, 0 = always)","example":0},"autoOptoutDuration":{"type":"string","description":"Auto opt-out duration configuration (JSON)","example":"{\"days\":30,\"mode\":\"inactive\"}"},"autoOptoutMessage":{"type":"string","description":"Message sent when a recipient is automatically opted out","example":"You have been automatically removed from this target group."},"autoOptoutDeclineMessage":{"type":"string","description":"Message sent when a re-opt-in is no longer allowed","example":"A renewed self-service registration is no longer allowed for this target group."},"optinMediaId":{"type":"object","description":"Media-library item id attached to the opt-in message","example":42,"nullable":true},"optoutMediaId":{"type":"object","description":"Media-library item id attached to the opt-out message","example":42,"nullable":true},"autoOptoutMediaId":{"type":"object","description":"Media-library item id attached to the auto-opt-out message","example":42,"nullable":true},"autoOptoutDeclineMediaId":{"type":"object","description":"Media-library item id attached to the decline message","example":42,"nullable":true},"optinMediaMimeType":{"type":"object","description":"MIME type of the opt-in media; needed to render it on load","example":"image/jpeg","nullable":true},"optoutMediaMimeType":{"type":"object","description":"MIME type of the opt-out media; needed to render it on load","example":"image/jpeg","nullable":true},"autoOptoutMediaMimeType":{"type":"object","description":"MIME type of the auto-opt-out media; needed to render it on load","example":"video/mp4","nullable":true},"autoOptoutDeclineMediaMimeType":{"type":"object","description":"MIME type of the decline media; needed to render it on load","example":"image/jpeg","nullable":true},"createdAt":{"type":"object","description":"ISO 8601 creation timestamp","example":"2025-01-01T00:00:00.000Z"},"updatedAt":{"type":"object","description":"ISO 8601 last update timestamp","example":"2025-01-01T00:00:00.000Z"},"folderId":{"type":"object","description":"Object folder ID","example":1}},"required":["id","externalId","name","description","channelId","color","tags","recipientCount","optInOutEnabled","optInOutTagId","optInCommands","optInMessage","optOutMessage","autoOptoutStatus","autoOptoutReoptin","autoOptoutDuration","autoOptoutMessage","autoOptoutDeclineMessage","createdAt","updatedAt","folderId"]},"UpdateSegmentationDto":{"type":"object","properties":{"name":{"type":"string","description":"Segmentation name","example":"Updated Segment Name"},"description":{"type":"string","description":"Description","example":"Updated description"},"color":{"type":"string","description":"Color for visual identification","example":"#FF5733"},"tags":{"type":"string","description":"Tags for filtering recipients (comma-separated)","example":"vip,premium"},"enableOptInOut":{"type":"boolean","description":"Enable opt-in/out functionality","example":true},"optInOutTagId":{"type":"number","description":"Assigned target tag for opt-in/out automation","example":42},"optInCommands":{"type":"string","description":"Opt-in commands (comma-separated)","example":"JOIN,START"},"optInMessage":{"type":"string","description":"Opt-in message","example":"You have successfully joined!"},"optOutMessage":{"type":"string","description":"Opt-out message","example":"You have been removed."},"autoOptoutStatus":{"type":"number","description":"Auto opt-out status","example":1},"autoOptoutReoptin":{"type":"number","description":"Allowed number of self-service re-opt-ins (-1 = never, 0 = always)","example":0},"autoOptoutDuration":{"type":"string","description":"Auto opt-out duration configuration (JSON)","example":"{\"mins\":0,\"hours\":0,\"days\":30,\"years\":0}"},"autoOptoutMessage":{"type":"string","description":"Message sent when a recipient is automatically opted out","example":"You have been automatically removed from this target group."},"autoOptoutDeclineMessage":{"type":"string","description":"Message sent when a re-opt-in is no longer allowed","example":"A renewed self-service registration is no longer allowed for this target group."},"optinMediaId":{"type":"object","description":"Media-library item id attached to the opt-in message (null clears it)","example":42,"nullable":true},"optoutMediaId":{"type":"object","description":"Media-library item id attached to the opt-out message (null clears it)","example":42,"nullable":true},"autoOptoutMediaId":{"type":"object","description":"Media-library item id attached to the auto-opt-out message (null clears it)","example":42,"nullable":true},"autoOptoutDeclineMediaId":{"type":"object","description":"Media-library item id attached to the decline message (null clears it)","example":42,"nullable":true},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"CreateShortLinkDto":{"type":"object","properties":{"originalUrl":{"type":"string","description":"Original/destination URL","example":"https://example.com/landing-page"},"referenceType":{"type":"string","description":"Reference type (b=broadcast, m=message, o=other)","example":"o","default":"o"},"referenceId":{"type":"number","description":"Reference ID (broadcast ID, message ID, etc.)","example":123},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["originalUrl"]},"UpdateShortLinkDto":{"type":"object","properties":{"originalUrl":{"type":"string","description":"Original/destination URL","example":"https://example.com/new-page"},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"CreateFeedDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID (deprecated - use Feed Targets instead)","example":1},"name":{"type":"string","description":"Feed name","example":"Tech News Feed","maxLength":250},"description":{"type":"string","description":"Feed description","example":"Daily technology news updates"},"color":{"type":"string","description":"Color code in hex format","example":"#0066CC"},"url":{"type":"string","description":"Feed source URL (RSS/XML)","example":"https://example.com/feed.xml"},"urlWhitelist":{"type":"string","description":"URL whitelist (one per line)","example":"example.com\ntrusted.com"},"urlBlacklist":{"type":"string","description":"URL blacklist (one per line)","example":"spam.com\nbad.com"},"message":{"type":"string","description":"Message template","example":"New article: {title}\n{link}"},"templateId":{"type":"number","description":"Template ID for message formatting","example":1},"fallbackTemplateId":{"type":"number","description":"Fallback template ID","example":2},"fallbackSkipDuplicate":{"type":"number","description":"Skip duplicate fallback items (0=no, 1=yes)","example":1,"default":0},"updateInterval":{"type":"number","description":"Update interval in minutes","example":60,"default":60},"sendInterval":{"type":"number","description":"Send interval in minutes","example":120,"default":120},"sendDateThreshold":{"type":"number","description":"Send date threshold in hours","example":24,"default":0},"broadcastApprove":{"type":"number","description":"Require broadcast approval (0=no, 1=yes)","example":0,"default":0},"broadcastSkipNoRecipients":{"type":"number","description":"Skip broadcast if no recipients (0=no, 1=yes)","example":1,"default":0},"broadcastExpireHours":{"type":"number","description":"Broadcast expiry time in hours","example":48,"default":0},"broadcastExpireDelete":{"type":"number","description":"Delete broadcasts after expiry (0=no, 1=yes)","example":0,"default":0},"titleKeywords":{"type":"string","description":"Required title keywords (comma-separated)","example":"tech,innovation"},"titleNegativeKeywords":{"type":"string","description":"Negative title keywords (comma-separated)","example":"ads,sponsored"},"titleUniqueness":{"type":"number","description":"Require unique titles (0=no, 1=yes)","example":1,"default":1},"requireUrl":{"type":"number","description":"Require URL in feed items (0=no, 1=yes)","example":1,"default":0},"requireValidUrl":{"type":"number","description":"Require valid URL format (0=no, 1=yes)","example":1,"default":0},"timeActivationStatus":{"type":"number","description":"Time activation status (0=inactive, 1=active)","example":0,"default":0},"timeActivationStart":{"type":"number","description":"Time activation start timestamp","example":1700000000},"timeActivationEnd":{"type":"number","description":"Time activation end timestamp","example":1710000000},"dayTimeActivationStatus":{"type":"number","description":"Day time activation status","example":0,"default":0},"dayTimeActivationStartHour":{"type":"number","description":"Day time activation start hour (0-23)","example":9},"dayTimeActivationEndHour":{"type":"number","description":"Day time activation end hour (0-23)","example":17},"feedbackLoopStatus":{"type":"number","description":"Feedback loop status (0=inactive, 1=active)","example":0,"default":0},"feedbackLoopId":{"type":"number","description":"Feedback loop ID","example":0,"default":0},"status":{"type":"boolean","description":"Active status. Accepts boolean true/false or string \"active\"/\"inactive\".","example":true,"default":true},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["name","url"]},"FeedResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Feed ID","example":1},"name":{"type":"string","description":"Feed name","example":"Tech News Feed"},"description":{"type":"string","description":"Feed description","example":"Daily technology news updates"},"color":{"type":"string","description":"Color code in hex format","example":"#FF5733"},"url":{"type":"string","description":"Feed source URL (RSS/XML)","example":"https://example.com/feed.xml"},"urlWhitelist":{"type":"string","description":"URL whitelist","example":"example.com\ntrusted.com"},"urlBlacklist":{"type":"string","description":"URL blacklist","example":"spam.com\nbad.com"},"message":{"type":"string","description":"Message template","example":"New article: {title}\n{link}"},"templateId":{"type":"object","description":"Template ID","example":1},"updateInterval":{"type":"number","description":"Update interval in minutes","example":60},"sendInterval":{"type":"number","description":"Send interval in minutes","example":120},"dateSendThreshold":{"type":"number","description":"Date send threshold in hours","example":24},"requiredTitleKeywords":{"type":"string","description":"Required title keywords (comma-separated)","example":"tech,innovation"},"requiredTitleNegativeKeywords":{"type":"string","description":"Negative title keywords (comma-separated)","example":"ads,sponsored"},"requiredTitleUniqueness":{"type":"number","description":"Required title uniqueness (0-100)","example":80,"minimum":0,"maximum":100},"requiredUrl":{"type":"boolean","description":"Require URL in feed items","example":false},"broadcastApprove":{"type":"boolean","description":"Require broadcast approval","example":false},"broadcastSkipNoRecipients":{"type":"boolean","description":"Skip broadcast if no recipients","example":false},"updateStatus":{"type":"number","description":"Update status (0=idle, 1=updating)","example":0},"error":{"type":"string","description":"Last error message","example":""},"broadcastExpire":{"type":"number","description":"Broadcast expiry in hours (0 = no expiry)","example":24},"broadcastExpireDelete":{"type":"number","description":"Delete broadcasts after expiry","example":0},"fallbackTemplateId":{"type":"object","description":"Fallback template ID","example":2},"fallbackSkipDuplicate":{"type":"boolean","description":"Skip duplicate fallback items","example":false},"timeactStatus":{"type":"number","description":"Time activation status (0=inactive, 1=active)","example":0},"timeactDateStart":{"type":"number","description":"Time activation start timestamp","example":0},"timeactDateEnd":{"type":"number","description":"Time activation end timestamp","example":0},"timeactDayStatus":{"type":"number","description":"Day time activation status (bitmask)","example":0},"timeactDayHoursStart":{"type":"string","description":"Day time activation start hour","example":"9"},"timeactDayHoursEnd":{"type":"string","description":"Day time activation end hour","example":"17"},"feedbackLoopStatus":{"type":"boolean","description":"Feedback loop status","example":false},"feedbackLoopId":{"type":"number","description":"Feedback loop ID","example":0},"numItems":{"type":"number","description":"Number of items in feed","example":0},"lastUpdate":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"lastCheck":{"type":"string","description":"Last check timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"lastSend":{"type":"string","description":"Last send timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"status":{"type":"string","description":"Active status","example":"active","enum":["active","inactive"]},"createdAt":{"type":"object","description":"Creation timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"updatedAt":{"type":"object","description":"Last update timestamp (ISO 8601) - alias for lastUpdate","example":"2023-11-14T16:53:20.000Z"},"folderId":{"type":"object","description":"Object folder ID","example":1}},"required":["id","name","description","color","url","urlWhitelist","urlBlacklist","message","templateId","updateInterval","sendInterval","dateSendThreshold","requiredTitleKeywords","requiredTitleNegativeKeywords","requiredTitleUniqueness","requiredUrl","broadcastApprove","broadcastSkipNoRecipients","updateStatus","error","broadcastExpire","broadcastExpireDelete","fallbackTemplateId","fallbackSkipDuplicate","timeactStatus","timeactDateStart","timeactDateEnd","timeactDayStatus","timeactDayHoursStart","timeactDayHoursEnd","feedbackLoopStatus","feedbackLoopId","numItems","lastUpdate","lastCheck","lastSend","status","createdAt","updatedAt","folderId"]},"UpdateFeedDto":{"type":"object","properties":{"name":{"type":"string","description":"Feed name","example":"Tech News Feed"},"description":{"type":"string","description":"Feed description","example":"Daily technology news updates"},"color":{"type":"string","description":"Color code in hex format","example":"#FF5733"},"url":{"type":"string","description":"Feed source URL (RSS/XML)","example":"https://example.com/feed.xml"},"urlWhitelist":{"type":"string","description":"URL whitelist (one per line)","example":"example.com\ntrusted.com"},"urlBlacklist":{"type":"string","description":"URL blacklist (one per line)","example":"spam.com\nbad.com"},"message":{"type":"string","description":"Message template","example":"New article: {title}\n{link}"},"templateId":{"type":"number","description":"Template ID for message formatting","example":1},"fallbackTemplateId":{"type":"number","description":"Fallback template ID","example":2},"fallbackSkipDuplicate":{"type":"number","description":"Skip duplicate fallback items (0=no, 1=yes)","example":1},"updateInterval":{"type":"number","description":"Update interval in minutes","example":60},"sendInterval":{"type":"number","description":"Send interval in minutes","example":120},"sendDateThreshold":{"type":"number","description":"Send date threshold in hours","example":24},"broadcastApprove":{"type":"number","description":"Require broadcast approval (0=no, 1=yes)","example":0},"broadcastSkipNoRecipients":{"type":"number","description":"Skip broadcast if no recipients (0=no, 1=yes)","example":1},"broadcastExpireHours":{"type":"number","description":"Broadcast expiry time in hours","example":48},"broadcastExpireDelete":{"type":"number","description":"Delete broadcasts after expiry (0=no, 1=yes)","example":0},"titleKeywords":{"type":"string","description":"Required title keywords (comma-separated)","example":"tech,innovation"},"titleNegativeKeywords":{"type":"string","description":"Negative title keywords (comma-separated)","example":"ads,sponsored"},"titleUniqueness":{"type":"number","description":"Require unique titles (0=no, 1=yes)","example":1},"requireUrl":{"type":"number","description":"Require URL in feed items (0=no, 1=yes)","example":1},"requireValidUrl":{"type":"number","description":"Require valid URL format (0=no, 1=yes)","example":1},"timeActivationStatus":{"type":"number","description":"Time activation status (0=inactive, 1=active)","example":0},"timeActivationStart":{"type":"number","description":"Time activation start timestamp","example":1700000000},"timeActivationEnd":{"type":"number","description":"Time activation end timestamp","example":1710000000},"dayTimeActivationStatus":{"type":"number","description":"Day time activation status","example":0},"dayTimeActivationStartHour":{"type":"number","description":"Day time activation start hour (0-23)","example":9},"dayTimeActivationEndHour":{"type":"number","description":"Day time activation end hour (0-23)","example":17},"feedbackLoopStatus":{"type":"number","description":"Feedback loop status (0=inactive, 1=active)","example":0},"feedbackLoopId":{"type":"number","description":"Feedback loop ID","example":0},"status":{"type":"boolean","description":"Active status. Accepts boolean true/false or string \"active\"/\"inactive\".","example":true},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"CreatePollDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID to associate with this poll","example":1},"name":{"type":"string","description":"Poll name/title","example":"Customer Satisfaction Survey"},"description":{"type":"string","description":"Poll description","example":"Help us improve our service"},"type":{"type":"string","description":"Poll type","example":"poll"},"color":{"type":"string","description":"Color code for poll UI","example":"#3498db"},"isActive":{"type":"boolean","description":"Active status","example":true,"default":true},"command":{"type":"string","description":"Command trigger for poll","example":"feedback"},"commandEnd":{"type":"string","description":"End command trigger","example":"done"},"welcomeMessage":{"type":"string","description":"Welcome message shown when poll starts","example":"Please share your feedback!"},"completionMessage":{"type":"string","description":"Message shown when poll is completed","example":"Thank you for your feedback!"},"errorMessage":{"type":"string","description":"Error message for invalid input","example":"Invalid selection, please try again"},"duplicateMessage":{"type":"string","description":"Message shown for duplicate votes","example":"You have already voted"},"allowMultipleVotes":{"type":"boolean","description":"Allow multiple votes per user","example":false,"default":false},"imageEnabled":{"type":"boolean","description":"Enable image display","example":false,"default":false},"imageCaption":{"type":"string","description":"Image caption","example":"Rate our service"},"imageInfo":{"type":"string","description":"Image info text","example":"Select an option below"},"imageFooter":{"type":"string","description":"Image footer text","example":"Powered by InstantKOM"},"imageTextColor":{"type":"string","description":"Image text color","example":"#FFFFFF"},"imageBackgroundColor":{"type":"string","description":"Image background color","example":"#000000"},"imageGridColor":{"type":"string","description":"Image grid color","example":"#CCCCCC"},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["channelId","name"]},"PollResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Poll ID","example":1},"channelId":{"type":"number","description":"Associated channel ID","example":1},"externalId":{"type":"string","description":"External ID (10 characters)","example":"XyZ9aB1cD2"},"name":{"type":"string","description":"Poll name/title","example":"Customer Satisfaction Survey"},"description":{"type":"string","description":"Poll description","example":"Help us improve our service"},"type":{"type":"string","description":"Poll type","example":"poll"},"color":{"type":"string","description":"Color code for poll UI","example":"#3498db"},"isActive":{"type":"boolean","description":"Active status","example":true},"command":{"type":"string","description":"Command trigger for poll","example":"feedback"},"commandEnd":{"type":"string","description":"End command trigger","example":"done"},"welcomeMessage":{"type":"string","description":"Welcome message shown when poll starts"},"completionMessage":{"type":"string","description":"Message shown when poll is completed"},"errorMessage":{"type":"string","description":"Error message for invalid input"},"duplicateMessage":{"type":"string","description":"Message shown for duplicate votes"},"impressions":{"type":"number","description":"Total number of impressions/views","example":150},"responses":{"type":"number","description":"Total number of responses/votes","example":42},"allowMultipleVotes":{"type":"boolean","description":"Allow multiple votes per user","example":false},"imageEnabled":{"type":"boolean","description":"Enable image display","example":false},"imageCaption":{"type":"string","description":"Image caption"},"imageInfo":{"type":"string","description":"Image info text"},"imageFooter":{"type":"string","description":"Image footer text"},"imageTextColor":{"type":"string","description":"Image text color"},"imageBackgroundColor":{"type":"string","description":"Image background color"},"imageGridColor":{"type":"string","description":"Image grid color"},"createdAt":{"type":"string","description":"Creation timestamp (ISO 8601)","example":"2025-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2025-01-15T14:45:00.000Z"},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["id","channelId","externalId","name","isActive","impressions","responses","allowMultipleVotes","imageEnabled"]},"UpdatePollDto":{"type":"object","properties":{"name":{"type":"string","description":"Poll name/title","example":"Customer Satisfaction Survey"},"description":{"type":"string","description":"Poll description","example":"Help us improve our service"},"type":{"type":"string","description":"Poll type","example":"poll"},"color":{"type":"string","description":"Color code for poll UI","example":"#3498db"},"isActive":{"type":"boolean","description":"Active status","example":true},"command":{"type":"string","description":"Command trigger for poll","example":"feedback"},"commandEnd":{"type":"string","description":"End command trigger","example":"done"},"welcomeMessage":{"type":"string","description":"Welcome message shown when poll starts","example":"Please share your feedback!"},"completionMessage":{"type":"string","description":"Message shown when poll is completed","example":"Thank you for your feedback!"},"errorMessage":{"type":"string","description":"Error message for invalid input","example":"Invalid selection, please try again"},"duplicateMessage":{"type":"string","description":"Message shown for duplicate votes","example":"You have already voted"},"allowMultipleVotes":{"type":"boolean","description":"Allow multiple votes per user","example":false},"imageEnabled":{"type":"boolean","description":"Enable image display","example":false},"imageCaption":{"type":"string","description":"Image caption","example":"Rate our service"},"imageInfo":{"type":"string","description":"Image info text","example":"Select an option below"},"imageFooter":{"type":"string","description":"Image footer text","example":"Powered by InstantKOM"},"imageTextColor":{"type":"string","description":"Image text color","example":"#FFFFFF"},"imageBackgroundColor":{"type":"string","description":"Image background color","example":"#000000"},"imageGridColor":{"type":"string","description":"Image grid color","example":"#CCCCCC"},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"CreateTicketDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID to associate with this ticket","example":1},"subject":{"type":"string","description":"Ticket subject/title","example":"Issue with message delivery"},"recipientId":{"type":"number","description":"Existing contact/recipient ID (alternative to email/name)","example":123},"email":{"type":"string","description":"Customer email address (required if no recipientId)","example":"customer@example.com"},"name":{"type":"string","description":"Customer name (required if no recipientId)","example":"John Doe"},"title":{"type":"string","description":"Customer title/salutation","example":"Premium Customer"},"gender":{"description":"Customer gender","example":"unknown","allOf":[{"$ref":"#/components/schemas/Gender"}]},"company":{"type":"string","description":"Company name","example":"Acme Corp"},"priority":{"description":"Ticket priority","example":"normal","allOf":[{"$ref":"#/components/schemas/TicketPriority"}]},"source":{"type":"string","description":"Source of ticket (e.g. email, whatsapp, telegram)","example":"email"},"recipients":{"type":"string","description":"Additional recipients (comma-separated)","example":"support@example.com,admin@example.com"},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["subject"]},"UpdateTicketDto":{"type":"object","properties":{"subject":{"type":"string","description":"Ticket subject/title","example":"Issue with message delivery"},"email":{"type":"string","description":"Customer email address","example":"customer@example.com"},"name":{"type":"string","description":"Customer name","example":"John Doe"},"title":{"type":"string","description":"Customer title/salutation","example":"Premium Customer"},"gender":{"description":"Customer gender","example":"unknown","allOf":[{"$ref":"#/components/schemas/Gender"}]},"company":{"type":"string","description":"Company name","example":"Acme Corp"},"status":{"description":"Ticket status","example":"open","allOf":[{"$ref":"#/components/schemas/TicketStatus"}]},"priority":{"description":"Ticket priority","example":"normal","allOf":[{"$ref":"#/components/schemas/TicketPriority"}]},"assignedTo":{"type":"object","description":"User ID to assign ticket to (null to unassign)","example":1,"nullable":true},"source":{"type":"string","description":"Source of ticket (e.g. email, whatsapp, telegram)","example":"email"},"recipients":{"type":"string","description":"Additional recipients (comma-separated)","example":"support@example.com,admin@example.com"},"isSpam":{"type":"boolean","description":"Mark ticket as spam","example":false},"folderId":{"type":"number","description":"Object folder ID","example":1},"notify":{"type":"boolean","description":"Trigger the legacy notification chain for transitions that have one. When `assignedTo` is set/changed, fires TICKET_ASSIGN (assignee email plus optional customer reply driven by the channel `tickets_assign_reply_sts`). When `status` transitions to `closed`, fires TICKET_CLOSE (optional customer reply driven by `tickets_close_reply_sts`). Defaults to true to mirror the legacy ticket-system UI behaviour. Set to false for silent API-driven updates (e.g. bulk re-routing or automated close).","example":true,"default":true}}},"CreateTicketMessageDto":{"type":"object","properties":{"message":{"type":"string","description":"Message content","example":"Thank you for your inquiry. We will look into this issue and get back to you shortly."}},"required":["message"]},"ReplyTicketDto":{"type":"object","properties":{"message":{"type":"string","description":"Reply body sent to the ticket customer. Provide RAW TEXT ONLY -- never include a salutation or sign-off: for email-channel tickets the ticket system auto-wraps the body with the personalised salutation (from `tickets.title`) and the localised footer (`lcl_mail_footer_salutation`). Adding your own greetings produces duplicated headers/footers.","example":"Vielen Dank für Ihre Anfrage. Wir kümmern uns umgehend darum."},"close":{"type":"boolean","description":"Close the ticket after the reply has been sent","default":false}},"required":["message"]},"CreateSuperWidgetDto":{"type":"object","properties":{"name":{"type":"string","description":"SuperWidget name","example":"Multi-Channel Registration"},"color":{"type":"string","description":"Primary color (hex)","example":"#3498db","default":"#3498db"},"customCss":{"type":"string","description":"Custom CSS styles"},"widgetIds":{"description":"Widget IDs to include in this SuperWidget","example":[1,2,3],"type":"array","items":{"type":"string"}},"selectedWidgetId":{"type":"number","description":"Widget ID that should be opened by default","example":2},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["name"]},"SuperWidgetResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"SuperWidget ID","example":1},"externalId":{"type":"string","description":"External ID","example":"XyZ9aB1cD2"},"embedId":{"type":"string","description":"Clean embed ID for /public/embed/superwidget routes","example":"abc123def456"},"name":{"type":"string","description":"SuperWidget name","example":"Multi-Channel Registration"},"color":{"type":"string","description":"Primary color (hex)","example":"#3498db"},"customCss":{"type":"string","description":"Custom CSS styles"},"widgetIds":{"description":"Widget IDs included in this SuperWidget","example":[1,2,3],"type":"array","items":{"type":"string"}},"selectedWidgetId":{"type":"number","description":"Widget ID that should be opened by default","example":2},"createdAt":{"type":"string","description":"Creation timestamp (ISO 8601)","example":"2025-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2025-01-15T14:45:00.000Z"},"folderId":{"type":"number","description":"Object folder ID","example":1}},"required":["id","externalId","embedId","name","color","widgetIds"]},"UpdateSuperWidgetDto":{"type":"object","properties":{"name":{"type":"string","description":"SuperWidget name"},"color":{"type":"string","description":"Primary color (hex)"},"customCss":{"type":"string","description":"Custom CSS styles"},"widgetIds":{"description":"Widget IDs to include","type":"array","items":{"type":"string"}},"selectedWidgetId":{"type":"number","description":"Widget ID that should be opened by default (0 clears the selection)","example":2},"folderId":{"type":"number","description":"Object folder ID","example":1}}},"CreateFlowDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID this flow belongs to","example":5},"name":{"type":"string","description":"Flow name","example":"Welcome Flow","maxLength":80},"description":{"type":"string","description":"Flow description","example":"Handles new user onboarding"},"color":{"type":"string","description":"Color for flow identification","example":"#3498DB","default":"#3498DB"},"folderId":{"type":"number","description":"Folder ID for organization","example":1},"status":{"type":"boolean","description":"Flow status (active/inactive)","example":false,"default":false},"eventKey":{"type":"string","description":"Event trigger this flow is bound to (event_key). Must be an event_key the account is allowed to use -- system-only triggers are rejected. See GET /app/flows/allowed-triggers.","example":"optin_confirmed","maxLength":64},"eventEnabled":{"type":"boolean","description":"Whether the bound event trigger is enabled. Only meaningful together with eventKey. Forced off when no eventKey is bound.","example":false,"default":false},"timeSchedule":{"type":"string","description":"Time-trigger schedule (#5108). Format \"daily:HH:MM\" (one cohort start per day from HH:MM on) or \"interval:<minutes>\" (one cohort start per interval bucket, minutes >= 1).","example":"daily:11:00","maxLength":64},"timeEnabled":{"type":"boolean","description":"Whether the time trigger is enabled. Only meaningful together with timeSchedule. Forced off when no schedule is set.","example":false,"default":false}},"required":["channelId","name"]},"FlowNodeResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Node ID","example":1},"externalId":{"type":"string","description":"External ID","example":"aBc1234567"},"flowId":{"type":"number","description":"Flow ID","example":1},"botId":{"type":"number","description":"Bot ID (only set for bot-type nodes, null otherwise)","example":5,"nullable":true},"positionX":{"type":"number","description":"X position on canvas","example":250.5},"positionY":{"type":"number","description":"Y position on canvas","example":100},"nodeType":{"type":"string","description":"Node type","example":"bot","enum":["entry","bot","exit","delay","condition","action","send_email"]},"delayMinutes":{"type":"object","description":"Delay in minutes","example":30,"nullable":true},"delayHours":{"type":"object","description":"Delay in hours","example":2,"nullable":true},"delayDays":{"type":"object","description":"Delay in days","example":1,"nullable":true},"conditionType":{"type":"object","description":"Condition type","example":"tag_has","nullable":true},"conditionValue":{"type":"object","description":"Condition value","example":"42","nullable":true},"actionType":{"type":"object","description":"Action type","example":"tag_add","nullable":true},"actionValue":{"type":"object","description":"Action value","example":"42","nullable":true},"mailType":{"type":"object","description":"System e-mail type for send_email nodes (curated allowlist). Stored in action_value.","example":"account-reminder","nullable":true},"botName":{"type":"string","description":"Bot name (bot nodes only)","example":"Welcome Bot"},"botColor":{"type":"string","description":"Bot color (bot nodes only)","example":"#3498db"},"botType":{"type":"string","description":"Bot type (bot nodes only)","example":"keyword"},"botLastRunAt":{"type":"object","description":"Bot last run timestamp (ISO 8601)","example":"2024-11-13T08:15:43.000Z"},"botTestRuns":{"type":"number","description":"Bot test runs count","example":42},"botMatchCount":{"type":"number","description":"Bot total matches count","example":35},"botUniqueRecipientsCount":{"type":"number","description":"Bot unique recipients count","example":28},"botMatchesLast7Days":{"type":"number","description":"Bot matches in last 7 days","example":12},"botMatchesLast30Days":{"type":"number","description":"Bot matches in last 30 days","example":35},"botLastMatchAt":{"type":"object","description":"Bot last match timestamp (ISO 8601)","example":"2024-11-12T14:30:00.000Z"}},"required":["id","externalId","flowId","botId","positionX","positionY","nodeType"]},"FlowEdgeResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Edge ID","example":1},"externalId":{"type":"string","description":"External ID","example":"aBc1234567"},"flowId":{"type":"number","description":"Flow ID","example":1},"sourceNodeId":{"type":"number","description":"Source node ID","example":1},"targetNodeId":{"type":"number","description":"Target node ID","example":2},"label":{"type":"string","description":"Edge label","example":"On Success"},"edgeType":{"type":"string","description":"Edge type","example":"default","enum":["default","true","false","matched","not_matched"]}},"required":["id","externalId","flowId","sourceNodeId","targetNodeId","edgeType"]},"FlowResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Flow ID","example":1},"externalId":{"type":"string","description":"External ID","example":"aBc1234567"},"name":{"type":"string","description":"Flow name","example":"Welcome Flow"},"description":{"type":"string","description":"Flow description","example":"Handles new user onboarding"},"color":{"type":"string","description":"Color for flow identification","example":"#3498db"},"status":{"type":"boolean","description":"Active status","example":true},"channelId":{"type":"number","description":"Channel ID","example":5},"folderId":{"type":"number","description":"Folder ID for organization","example":1},"eventKey":{"type":"string","description":"Event trigger this flow is bound to (event_key), if any. System-only triggers are never persisted via the user API.","example":"optin_confirmed"},"eventEnabled":{"type":"boolean","description":"Whether the bound event trigger is enabled.","example":false},"timeSchedule":{"type":"string","description":"Time-trigger schedule (\"daily:HH:MM\" or \"interval:<minutes>\"), if any.","example":"daily:11:00"},"timeEnabled":{"type":"boolean","description":"Whether the time trigger is enabled.","example":false},"instances":{"type":"number","description":"Number of recorded flow executions","example":42},"createdAt":{"type":"string","description":"Creation timestamp (ISO 8601)","example":"2025-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2025-01-15T14:45:00.000Z"},"nodes":{"description":"Flow nodes (bot placements)","type":"array","items":{"$ref":"#/components/schemas/FlowNodeResponseDto"}},"edges":{"description":"Flow edges (connections between nodes)","type":"array","items":{"$ref":"#/components/schemas/FlowEdgeResponseDto"}}},"required":["id","externalId","name","color","status","channelId","createdAt","updatedAt"]},"UpdateFlowDto":{"type":"object","properties":{"channelId":{"type":"number","description":"Channel ID this flow belongs to","example":5},"name":{"type":"string","description":"Flow name","example":"Welcome Flow","maxLength":80},"description":{"type":"string","description":"Flow description","example":"Handles new user onboarding"},"color":{"type":"string","description":"Color for flow identification","example":"#3498DB","default":"#3498DB"},"folderId":{"type":"number","description":"Folder ID for organization","example":1},"status":{"type":"boolean","description":"Active status","example":true,"default":false},"eventKey":{"type":"string","description":"Event trigger this flow is bound to (event_key). Must be an event_key the account is allowed to use -- system-only triggers are rejected. See GET /app/flows/allowed-triggers.","example":"optin_confirmed","maxLength":64},"eventEnabled":{"type":"boolean","description":"Whether the bound event trigger is enabled. Only meaningful together with eventKey. Forced off when no eventKey is bound.","example":false,"default":false},"timeSchedule":{"type":"string","description":"Time-trigger schedule (#5108). Format \"daily:HH:MM\" (one cohort start per day from HH:MM on) or \"interval:<minutes>\" (one cohort start per interval bucket, minutes >= 1).","example":"daily:11:00","maxLength":64},"timeEnabled":{"type":"boolean","description":"Whether the time trigger is enabled. Only meaningful together with timeSchedule. Forced off when no schedule is set.","example":false,"default":false}}},"CreateFlowNodeDto":{"type":"object","properties":{"nodeType":{"type":"string","description":"Node type. Determines which fields are required: bot -> botId; delay -> delayMinutes/Hours/Days; condition -> conditionType+conditionValue; action -> actionType+actionValue.","example":"bot","enum":["entry","bot","exit","delay","condition","action","send_email"]},"positionX":{"type":"number","description":"X position on canvas","example":250.5},"positionY":{"type":"number","description":"Y position on canvas","example":100},"botId":{"type":"number","description":"Bot ID. REQUIRED when nodeType=bot, must be omitted otherwise.","example":5},"delayMinutes":{"type":"number","description":"Delay in minutes (delay nodes only)","example":30},"delayHours":{"type":"number","description":"Delay in hours (delay nodes only)","example":2},"delayDays":{"type":"number","description":"Delay in days (delay nodes only)","example":1},"conditionType":{"type":"string","description":"Condition type (condition nodes only)","example":"tag_has","enum":["tag_has","tag_not_has","env_equals","last_bot_matched","has_contact"]},"conditionValue":{"type":"string","description":"Condition value (condition nodes only). Format depends on conditionType: tag id, env key=value, etc.","example":"42"},"actionType":{"type":"string","description":"Action type (action nodes only)","example":"tag_add","enum":["tag_add","tag_remove","env_set","env_delete"]},"actionValue":{"type":"string","description":"Action value (action nodes only). Format depends on actionType: tag id for tag_add/remove, key=value for env_set, key for env_delete.","example":"42"},"mailType":{"type":"string","description":"System e-mail type to send (send_email nodes only). Must be one of the curated, flow-eligible mail types. Persisted in action_value and dispatched via the policy-conformant ViewMail pipeline (NOT the raw bot-text path).","example":"account-reminder","enum":["account-reminder","trial-expires-3days","trial-expires-1day","account-credit-alert","account-archive-warning","account-delete-warning"]}},"required":["nodeType","positionX","positionY"]},"UpdateFlowNodeDto":{"type":"object","properties":{"nodeType":{"type":"string","description":"Node type. Determines which fields are required: bot -> botId; delay -> delayMinutes/Hours/Days; condition -> conditionType+conditionValue; action -> actionType+actionValue.","example":"bot","enum":["entry","bot","exit","delay","condition","action","send_email"]},"positionX":{"type":"number","description":"X position on canvas","example":250.5},"positionY":{"type":"number","description":"Y position on canvas","example":100},"botId":{"type":"number","description":"Bot ID. REQUIRED when nodeType=bot, must be omitted otherwise.","example":5},"delayMinutes":{"type":"number","description":"Delay in minutes (delay nodes only)","example":30},"delayHours":{"type":"number","description":"Delay in hours (delay nodes only)","example":2},"delayDays":{"type":"number","description":"Delay in days (delay nodes only)","example":1},"conditionType":{"type":"string","description":"Condition type (condition nodes only)","example":"tag_has","enum":["tag_has","tag_not_has","env_equals","last_bot_matched","has_contact"]},"conditionValue":{"type":"string","description":"Condition value (condition nodes only). Format depends on conditionType: tag id, env key=value, etc.","example":"42"},"actionType":{"type":"string","description":"Action type (action nodes only)","example":"tag_add","enum":["tag_add","tag_remove","env_set","env_delete"]},"actionValue":{"type":"string","description":"Action value (action nodes only). Format depends on actionType: tag id for tag_add/remove, key=value for env_set, key for env_delete.","example":"42"},"mailType":{"type":"string","description":"System e-mail type to send (send_email nodes only). Must be one of the curated, flow-eligible mail types. Persisted in action_value and dispatched via the policy-conformant ViewMail pipeline (NOT the raw bot-text path).","example":"account-reminder","enum":["account-reminder","trial-expires-3days","trial-expires-1day","account-credit-alert","account-archive-warning","account-delete-warning"]}}},"CreateFlowEdgeDto":{"type":"object","properties":{"sourceNodeId":{"type":"number","description":"Source node ID","example":1},"targetNodeId":{"type":"number","description":"Target node ID","example":2},"label":{"type":"string","description":"Edge label","example":"true branch","maxLength":80},"edgeType":{"type":"string","description":"Edge type. Use `true`/`false` for condition branches, `matched`/`not_matched` for bot branches, `default` everywhere else.","example":"default","enum":["default","true","false","matched","not_matched"]}},"required":["sourceNodeId","targetNodeId","edgeType"]},"UpdateFlowEdgeDto":{"type":"object","properties":{"sourceNodeId":{"type":"number","description":"Source node ID","example":1},"targetNodeId":{"type":"number","description":"Target node ID","example":2},"label":{"type":"string","description":"Edge label","example":"true branch","maxLength":80},"edgeType":{"type":"string","description":"Edge type. Use `true`/`false` for condition branches, `matched`/`not_matched` for bot branches, `default` everywhere else.","example":"default","enum":["default","true","false","matched","not_matched"]}}},"BotEnvVarsCreateBotEnvVarDto":{"type":"object","properties":{"key":{"type":"string","description":"Variable key/name (unique per user, max 16 characters, alphanumeric + underscore)","example":"customer_tier","maxLength":16},"description":{"type":"string","description":"Variable description","example":"Customer tier level for pricing","maxLength":2000},"color":{"type":"string","description":"Variable color (hex format)","example":"#3B82F6","default":"#3B82F6"},"folderId":{"type":"number","description":"Object folder ID","example":12}},"required":["key"]},"BotEnvVarsBotEnvVarResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Variable ID","example":123},"key":{"type":"string","description":"Variable key/name","example":"customer_tier"},"name":{"type":"string","description":"User-facing variable name","example":"Customer tier"},"description":{"type":"string","description":"Variable description","example":"Customer tier level for pricing"},"color":{"type":"string","description":"Variable color (hex format)","example":"#3B82F6"},"folderId":{"type":"number","description":"Object folder ID","example":12},"recipientCount":{"type":"number","description":"Number of recipients with values for this variable","example":42},"botCount":{"type":"number","description":"Number of bots using this variable","example":3},"valueType":{"type":"string","description":"Stored value type","example":"text"},"usage":{"type":"number","description":"Total usage references across recipients and bots","example":45},"createdAt":{"type":"string","description":"Creation timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"},"updatedAt":{"type":"string","description":"Last update timestamp (ISO 8601)","example":"2023-11-14T16:53:20.000Z"}},"required":["id","key","name","color","recipientCount","botCount","valueType","usage","createdAt","updatedAt"]},"BotEnvVarsUpdateBotEnvVarDto":{"type":"object","properties":{"description":{"type":"string","description":"Variable description","example":"Customer tier level for pricing","maxLength":2000},"color":{"type":"string","description":"Variable color (hex format)","example":"#3B82F6"},"folderId":{"type":"number","description":"Object folder ID","example":12}}},"BotEnvVarValueResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"Value ID","example":456},"recipientId":{"type":"number","description":"Recipient ID","example":789},"recipientName":{"type":"string","description":"Recipient name","example":"John Doe"},"recipientIdentifier":{"type":"string","description":"Recipient identifier (phone number, username, etc.)","example":"+491701234567"},"key":{"type":"string","description":"Variable key","example":"customer_tier"},"value":{"type":"string","description":"Current value","example":"premium"},"pendingValue":{"type":"string","description":"Pending new value (if any)","example":"enterprise"},"createdAt":{"type":"number","description":"Creation timestamp (Unix)","example":1700000000},"updatedAt":{"type":"number","description":"Last update timestamp (Unix)","example":1700100000},"expiresAt":{"type":"number","description":"Expiration timestamp (Unix, 0 if no expiration)","example":1705000000}},"required":["id","recipientId","key","value","createdAt","updatedAt"]},"BotEnvVarBotUsageDto":{"type":"object","properties":{"id":{"type":"number","description":"Bot ID","example":123},"name":{"type":"string","description":"Bot name","example":"Welcome Bot"},"status":{"type":"boolean","description":"Bot status (active/inactive)","example":true},"setValue":{"type":"string","description":"Value the bot sets for this variable","example":"premium"},"color":{"type":"string","description":"Bot color","example":"#10B981"},"channelId":{"type":"number","description":"Channel ID the bot belongs to","example":505},"channelName":{"type":"string","description":"Channel name","example":"Main Channel"}},"required":["id","name","status","setValue","channelId"]},"UpdateBotEnvValueDto":{"type":"object","properties":{"value":{"type":"string","description":"Current value","example":"premium","maxLength":65535},"expiresAt":{"type":"number","description":"Expiration timestamp (Unix, 0 for no expiration)","example":1705000000}}},"CustomFieldValueResponseDto":{"type":"object","properties":{"fieldId":{"type":"number","description":"Custom field definition ID","example":1},"fieldKey":{"type":"string","description":"Field key","example":"customer_id"},"fieldName":{"type":"string","description":"Field name","example":"Kundennummer"},"fieldType":{"type":"string","description":"Field type","example":"text"},"options":{"description":"Available options for dropdown/select fields","example":["S","M","L"],"type":"array","items":{"type":"string"}},"value":{"type":"string","description":"Field value","example":"K-12345"},"updatedAt":{"type":"string","description":"Last update timestamp","example":"2024-01-15T10:30:00Z"}},"required":["fieldId","fieldKey","fieldName","fieldType"]},"SetCustomFieldValuesDto":{"type":"object","properties":{"values":{"type":"object","description":"Object with field keys as keys and values as values","example":{"customer_id":"K-12345","birthday":"1990-05-15","vip_status":"true"},"additionalProperties":{"type":"string"}}},"required":["values"]}}},"externalDocs":{"description":"Learn more about instantKOM","url":"https://start.instantkom.app"}}