import {z} from 'zod' export type ASRConversationalConfigOverride = {keywords?: (Array | null) | undefined}; export type SoftTimeoutConfigOverride = {message?: (string | null) | undefined, additional_soft_timeout_messages?: (Array | null) | undefined}; export type TurnConfigOverride = {soft_timeout_config?: (SoftTimeoutConfigOverride | null) | undefined, noisy_environment_message?: (string | null) | undefined}; export type TTSModelFamily = 'turbo' | 'flash' | 'multilingual' | 'v3_conversational' | 'v4' | 'v4_turbo'; export type TTSOptimizeStreamingLatency = 0 | 1 | 2 | 3 | 4; export type SupportedVoice = {label: string, voice_id: string, description?: (string | null) | undefined, language?: (string | null) | undefined, model_family?: (TTSModelFamily | null) | undefined, optimize_streaming_latency?: (TTSOptimizeStreamingLatency | null) | undefined, stability?: (number | null) | undefined, speed?: (number | null) | undefined, similarity_boost?: (number | null) | undefined, clone_strength?: (number | null) | undefined}; export type PydanticPronunciationDictionaryVersionLocator = {pronunciation_dictionary_id: string, version_id: string | null}; export type TTSConversationalConfigOverride = {model_id?: ('eleven_turbo_v2' | 'eleven_turbo_v2_5' | 'eleven_flash_v2' | 'eleven_flash_v2_5' | 'eleven_multilingual_v2' | 'eleven_v3_conversational' | 'eleven_v4' | 'eleven_v4_turbo' | null) | undefined, voice_id?: (string | null) | undefined, supported_voices?: (Array | null) | undefined, stability?: (number | null) | undefined, speed?: (number | null) | undefined, similarity_boost?: (number | null) | undefined, clone_strength?: (number | null) | undefined, pronunciation_dictionary_locators?: (Array | null) | undefined}; export type ConversationConfigOverride = {text_only?: (boolean | null) | undefined, max_duration_seconds?: (number | null) | undefined}; export type KnowledgeBaseDocumentType = 'file' | 'url' | 'text' | 'folder'; export type DocumentUsageModeEnum = 'prompt' | 'auto'; export type KnowledgeBaseLocator = {type: KnowledgeBaseDocumentType, name: string, id: string, usage_mode?: DocumentUsageModeEnum | undefined}; export type PromptAgentAPIModelOverrideInput = {prompt?: (string | null) | undefined, llm?: ('gpt-4o-mini' | 'gpt-4o' | 'gpt-4' | 'gpt-4-turbo' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4.1-nano' | 'gpt-5' | 'gpt-5.1' | 'gpt-5.2' | 'gpt-5.2-chat-latest' | 'gpt-5.4' | 'gpt-5.4-mini' | 'gpt-5.4-nano' | 'gpt-5.5' | 'gpt-5.6-sol' | 'gpt-5.6-terra' | 'gpt-5.6-luna' | 'gpt-6-astra' | 'gpt-6-sol' | 'gpt-6-luna' | 'gpt-6.1-sol' | 'gpt-6.1-terra' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-3.5-turbo' | 'gemini-1.5-pro' | 'gemini-1.5-flash' | 'gemini-2.0-flash' | 'gemini-2.0-flash-lite' | 'gemini-2.5-flash-lite' | 'gemini-2.5-flash' | 'gemini-3-pro-preview' | 'gemini-3-flash-preview' | 'gemini-3.1-pro-preview' | 'gemini-3.1-flash-lite-preview' | 'gemini-3.1-flash-lite' | 'gemini-3.5-flash' | 'gemini-3.5-flash-lite' | 'gemini-3.6-flash' | 'gemini-3.7-flash' | 'gemini-3.8-flash' | 'gemini-4-argon' | 'claude-sonnet-4-5' | 'claude-opus-4-6' | 'claude-opus-4-7' | 'claude-opus-4-8' | 'claude-opus-5' | 'claude-opus-5-5' | 'claude-sonnet-4-6' | 'claude-sonnet-5' | 'claude-sonnet-5-5' | 'claude-sonnet-4' | 'claude-haiku-4-5' | 'claude-haiku-5-5' | 'claude-3-7-sonnet' | 'claude-3-5-sonnet' | 'claude-3-5-sonnet-v1' | 'claude-3-haiku' | 'grok-beta' | 'custom-llm' | 'qwen3-4b' | 'qwen3-30b-a3b' | 'qwen36-35b-a3b' | 'qwen35-397b-a17b' | 'gpt-oss-20b' | 'gpt-oss-120b' | 'glm-45-air-fp8' | 'glm-52' | 'deepseek-v41-flash' | 'nemotron-35-super-vl-nvfp4' | 'gemini-2.5-flash-preview-09-2025' | 'gemini-2.5-flash-lite-preview-09-2025' | 'gemini-2.5-flash-preview-05-20' | 'gemini-2.5-flash-preview-04-17' | 'gemini-2.5-flash-lite-preview-06-17' | 'gemini-2.0-flash-lite-001' | 'gemini-2.0-flash-001' | 'gemini-1.5-flash-002' | 'gemini-1.5-flash-001' | 'gemini-1.5-pro-002' | 'gemini-1.5-pro-001' | 'claude-sonnet-4@20250514' | 'claude-sonnet-4-5@20250929' | 'claude-haiku-4-5@20251001' | 'claude-3-7-sonnet@20250219' | 'claude-3-5-sonnet@20240620' | 'claude-3-5-sonnet-v2@20241022' | 'claude-3-haiku@20240307' | 'gpt-5-2025-08-07' | 'gpt-5.1-2025-11-13' | 'gpt-5.2-2025-12-11' | 'gpt-5.4-2026-03-05' | 'gpt-5.4-mini-2026-03-17' | 'gpt-5.4-nano-2026-03-17' | 'gpt-5.5-2026-04-23' | 'gpt-5-mini-2025-08-07' | 'gpt-5-nano-2025-08-07' | 'gpt-4.1-2025-04-14' | 'gpt-4.1-mini-2025-04-14' | 'gpt-4.1-nano-2025-04-14' | 'gpt-4o-mini-2024-07-18' | 'gpt-4o-2024-11-20' | 'gpt-4o-2024-08-06' | 'gpt-4o-2024-05-13' | 'gpt-4-0613' | 'gpt-4-0314' | 'gpt-4-turbo-2024-04-09' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'watt-tool-8b' | 'watt-tool-70b' | null) | undefined, reasoning_effort?: ('none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null) | undefined, tool_ids?: (Array | null) | undefined, tool_ids_strict?: (boolean | null) | undefined, native_mcp_server_ids?: (Array | null) | undefined, knowledge_base?: (Array | null) | undefined}; export type AgentConfigOverrideInput = {first_message?: (string | null) | undefined, language?: (string | null) | undefined, max_conversation_duration_message?: (string | null) | undefined, prompt?: (PromptAgentAPIModelOverrideInput | null) | undefined}; export type ConversationConfigClientOverrideInput = {asr?: (ASRConversationalConfigOverride | null) | undefined, turn?: (TurnConfigOverride | null) | undefined, tts?: (TTSConversationalConfigOverride | null) | undefined, conversation?: (ConversationConfigOverride | null) | undefined, agent?: (AgentConfigOverrideInput | null) | undefined}; export type ConversationInitiationSource = 'unknown' | 'android_sdk' | 'node_js_sdk' | 'react_native_sdk' | 'react_sdk' | 'js_sdk' | 'python_sdk' | 'widget' | 'sip_trunk' | 'twilio' | 'exotel' | 'genesys' | 'avaya' | 'audiocodes' | 'swift_sdk' | 'whatsapp' | 'twilio_sms' | 'flutter_sdk' | 'zendesk_integration' | 'slack_integration' | 'telegram_integration' | 'intercom_integration' | 'freshdesk_integration' | 'salesforce_integration' | 'template_preview' | 'genesys_bot_connector' | 'subagent_tool'; export type ConversationInitiationSourceInfo = {source?: (ConversationInitiationSource | null) | undefined, version?: (string | null) | undefined}; export type ConversationInitiationClientDataRequestInput = {conversation_config_override?: ConversationConfigClientOverrideInput | undefined, custom_llm_extra_body?: {[key: string]: unknown} | undefined, user_id?: (string | null) | undefined, source_info?: ConversationInitiationSourceInfo | undefined, branch_id?: (string | null) | undefined, environment?: (string | null) | undefined, starting_workflow_node_id?: (string | null) | undefined, procedure_ids?: (Array | null) | undefined, start_procedure_ids?: (Array | null) | undefined, dynamic_variables?: {[key: string]: unknown} | undefined}; export type SubmitCampaignRecipient = {phone_number?: (string | null) | undefined, phone_numbers?: (Array | null) | undefined, whatsapp_user_id?: (string | null) | undefined, id?: (string | null) | undefined, conversation_initiation_client_data?: (ConversationInitiationClientDataRequestInput | null) | undefined}; export type IntervalPlacement = 'start' | 'random' | 'rotate'; export type RetryPolicy = {retry_delay_seconds?: number | undefined, max_short_retries?: number | undefined, max_total_calls?: number | undefined, max_callbacks?: number | undefined, max_redirects?: number | undefined, interval_placement?: IntervalPlacement | undefined, rotate_step_seconds?: number | undefined, max_consecutive_failures_per_number?: (number | null) | undefined}; export type CallingIntervalPolicy = {start: string, end: string}; export type CallingPeriod = {weekdays: Array, intervals: Array}; export type DataCollectionConfig = {callback_time?: (string | null) | undefined, redirect_phone_number?: (string | null) | undefined, stop?: (string | null) | undefined, mappings?: {[key: string]: string} | undefined}; export type FollowupContextPolicy = {call_type?: boolean | undefined, previous_conversation_id?: boolean | undefined, previous_summary?: boolean | undefined, previous_transcript?: boolean | undefined}; export type PolicyConfigInput = {timezone?: string | undefined, retry?: RetryPolicy | undefined, calling_periods?: Array | undefined, data_collection?: DataCollectionConfig | undefined, followup_context?: FollowupContextPolicy | undefined}; export type CampaignVariant = 'simple' | 'advanced'; export type TwilioMachineDetectionMode = 'enable' | 'detect_message_end'; export type TwilioMachineDetectionAction = 'hang_up'; export type TwilioAnsweredBy = 'human' | 'fax' | 'unknown' | 'machine_start' | 'machine_end_beep' | 'machine_end_silence' | 'machine_end_other'; export type TwilioMachineDetectionRule = {action: TwilioMachineDetectionAction, answered_by: Array}; export type TwilioMachineDetectionConfig = {mode?: TwilioMachineDetectionMode | undefined, actions?: Array | undefined}; export type PhoneVoiceConfigInput = {ringing_timeout_secs?: number | undefined, twilio_call_recording_enabled?: boolean | undefined, twilio_machine_detection?: (TwilioMachineDetectionConfig | null) | undefined, mode?: 'voice' | undefined}; export type PhoneChannelConfigInput = {channel?: 'phone' | undefined, agent_phone_number_id: string, mode_config?: PhoneVoiceConfigInput | undefined}; export type WhatsAppVoiceConfig = {mode?: 'voice' | undefined, whatsapp_call_permission_request_template_name: string, whatsapp_call_permission_request_template_language_code: string}; export type SubmitWhatsAppTemplateRef = {name: string, language: string}; export type SubmitWhatsAppMessageConfig = {mode?: 'message' | undefined, template: SubmitWhatsAppTemplateRef}; export type SubmitWhatsAppChannelConfig = {channel?: 'whatsapp' | undefined, whatsapp_phone_number_id: string, mode_config: WhatsAppVoiceConfig | SubmitWhatsAppMessageConfig}; export type SubmitCampaignRequest = {call_name: string, agent_id: string, recipients: Array, scheduled_time_unix?: (number | null) | undefined, timezone?: (string | null) | undefined, branch_id?: (string | null) | undefined, environment?: (string | null) | undefined, target_concurrency_limit?: (number | null) | undefined, idempotency_key?: (string | null) | undefined, policy?: (PolicyConfigInput | null) | undefined, variant?: (CampaignVariant | null) | undefined, channel_config: PhoneChannelConfigInput | SubmitWhatsAppChannelConfig}; export type CreateApiV1ConvaiOutboundCampaignsCampaignsSubmitArgs = {'xi-api-key'?: (string | null) | undefined, body: SubmitCampaignRequest}; export type CreateApiV1ConvaiOutboundCampaignsCampaignsSubmitOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const twilioMachineDetectionMode = z.enum(["enable", "detect_message_end"]); export const twilioMachineDetectionAction = z.literal("hang_up"); export const twilioAnsweredBy = z.enum(["human", "fax", "unknown", "machine_start", "machine_end_beep", "machine_end_silence", "machine_end_other"]); export const twilioMachineDetectionRule = z.object({action: twilioMachineDetectionAction, answered_by: z.array(twilioAnsweredBy)}); export const twilioMachineDetectionConfig = z.object({mode: twilioMachineDetectionMode.optional(), actions: z.array(twilioMachineDetectionRule).optional()}); export const phoneVoiceConfigOutput = z.object({ringing_timeout_secs: z.number().int().gte(1).lte(999).optional(), twilio_call_recording_enabled: z.boolean().optional(), twilio_machine_detection: twilioMachineDetectionConfig.nullable().optional(), mode: z.literal("voice").optional()}); export const phoneChannelConfigOutput = z.object({channel: z.literal("phone").optional(), agent_phone_number_id: z.string().min(1).max(256), mode_config: phoneVoiceConfigOutput.optional()}); export const whatsAppVoiceConfig = z.object({mode: z.literal("voice").optional(), whatsapp_call_permission_request_template_name: z.string(), whatsapp_call_permission_request_template_language_code: z.string()}); export const whatsAppTemplateComponentButton = z.object({type: z.string(), text: z.string().nullable().optional(), url: z.string().nullable().optional()}); export const whatsAppTemplateComponent = z.object({type: z.string(), format: z.string().nullable().optional(), text: z.string().nullable().optional(), buttons: z.array(whatsAppTemplateComponentButton).nullable().optional()}); export const whatsAppTemplate = z.object({name: z.string(), language: z.string(), parameter_format: z.enum(["POSITIONAL", "NAMED"]).optional(), components: z.array(whatsAppTemplateComponent), category: z.string().nullable().optional()}); export const whatsAppMessageConfig = z.object({mode: z.literal("message").optional(), template: whatsAppTemplate}); export const whatsAppChannelConfig = z.object({channel: z.literal("whatsapp").optional(), whatsapp_phone_number_id: z.string().min(1), mode_config: z.discriminatedUnion("mode", [whatsAppVoiceConfig, whatsAppMessageConfig])}); export const campaignStatus = z.enum(["active", "paused", "stopping", "stopped", "completed", "failed", "attention"]); export const intervalPlacement = z.enum(["start", "random", "rotate"]); export const retryPolicy = z.object({retry_delay_seconds: z.number().int().gt(0).optional(), max_short_retries: z.number().int().gte(0).lte(30).optional(), max_total_calls: z.number().int().gte(1).lte(30).optional(), max_callbacks: z.number().int().gte(0).lte(30).optional(), max_redirects: z.number().int().gte(0).lte(30).optional(), interval_placement: intervalPlacement.optional(), rotate_step_seconds: z.number().int().gt(0).optional(), max_consecutive_failures_per_number: z.number().int().gte(1).lte(30).nullable().optional()}); export const callingIntervalPolicy = z.object({start: z.string(), end: z.string()}); export const callingPeriodPolicy = z.object({weekdays: z.array(z.number().int()), intervals: z.array(callingIntervalPolicy)}); export const dataCollectionPolicy = z.object({callback_time: z.string().nullable().optional(), redirect_phone_number: z.string().nullable().optional(), stop: z.string().nullable().optional(), mappings: z.record(z.string(), z.string()).optional()}); export const followupContextPolicy = z.object({call_type: z.boolean().optional(), previous_conversation_id: z.boolean().optional(), previous_summary: z.boolean().optional(), previous_transcript: z.boolean().optional()}); export const campaignPolicySnapshot = z.object({timezone: z.string(), retry: retryPolicy, calling_periods: z.array(callingPeriodPolicy), data_collection: dataCollectionPolicy, followup_context: followupContextPolicy}); export const campaignVariant = z.enum(["simple", "advanced"]); export const campaignSource = z.enum(["ui", "api"]); export const outboundChannel = z.enum(["phone", "whatsapp"]); export const outboundMode = z.enum(["voice", "message"]); export const recipientDeliveryCounts = z.object({sent: z.number().int().optional(), delivered: z.number().int().optional(), read: z.number().int().optional(), replied: z.number().int().optional(), failed: z.number().int().optional()}); export const campaignSummaryCounts = z.object({leads: z.number().int(), terminal_leads: z.number().int(), open_attention: z.number().int(), delivery: recipientDeliveryCounts.nullable().optional()}); export const campaignResponse = z.object({campaign_id: z.string(), call_name: z.string(), agent_id: z.string(), channel_config: z.discriminatedUnion("channel", [phoneChannelConfigOutput, whatsAppChannelConfig]), status: campaignStatus, policy: campaignPolicySnapshot, variant: campaignVariant, source: campaignSource.nullable(), created_at_unix: z.number().int(), scheduled_time_unix: z.number().int().nullable(), updated_at_unix: z.number().int(), branch_id: z.string().nullable(), environment: z.string().nullable(), target_concurrency_limit: z.number().int().nullable(), channel: outboundChannel, mode: outboundMode, counts: campaignSummaryCounts, agent_name: z.string()}); export const submitCampaignResponse = z.object({campaign: campaignResponse, created: z.boolean(), within_calling_window: z.boolean()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Create An Outbound Campaign * * POST /v1/convai/outbound-campaigns/campaigns/submit */ export const createApiV1ConvaiOutboundCampaignsCampaignsSubmit = async (args: CreateApiV1ConvaiOutboundCampaignsCampaignsSubmitArgs, options: CreateApiV1ConvaiOutboundCampaignsCampaignsSubmitOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['xi-api-key'] != null) headers.set("xi-api-key", String(args['xi-api-key'])) const url = `${baseUrl.replace(/\/+$/, '')}/v1/convai/outbound-campaigns/campaigns/submit${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(submitCampaignResponse, await res.json()) };