diff --git a/specs/signalwire-rest/calling-api/calls/models/requests.tsp b/specs/signalwire-rest/calling-api/calls/models/requests.tsp
index f5cf1b338..635b26860 100644
--- a/specs/signalwire-rest/calling-api/calls/models/requests.tsp
+++ b/specs/signalwire-rest/calling-api/calls/models/requests.tsp
@@ -50,7 +50,19 @@ model CallHoldRequest {
command: "calling.ai_hold";
@doc(paramsDescription)
- params: {};
+ params: {
+ @doc("The duration to hold the caller in seconds.")
+ @example(300)
+ @maxValue(300)
+ timeout?: int32 = 300;
+
+ @doc("""
+ A system message added to the AI conversation before placing the caller on hold.
+ The AI will speak this message to the caller before hold music begins.
+ """)
+ @example("Please hold while I transfer you to a specialist.")
+ prompt?: string = "Tell the user you are putting them on hold.";
+ };
}
@summary("Unhold call")
@@ -64,7 +76,14 @@ model CallUnholdRequest {
command: "calling.ai_unhold";
@doc(paramsDescription)
- params: {};
+ params: {
+ @doc("""
+ A system message added to the AI conversation when taking the caller off hold.
+ The AI will use this context when resuming the conversation.
+ """)
+ @example("The user has been connected to a specialist.")
+ prompt?: string = "The user has been taken off hold.";
+ };
}
@summary("Inject AI message")
diff --git a/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml b/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml
index a829178a5..569890787 100644
--- a/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml
+++ b/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml
@@ -352,6 +352,21 @@ components:
example: calling.ai_hold
params:
type: object
+ properties:
+ timeout:
+ type: integer
+ format: int32
+ maximum: 300
+ description: The duration to hold the caller in seconds.
+ example: 300
+ default: 300
+ prompt:
+ type: string
+ description: |-
+ A system message added to the AI conversation before placing the caller on hold.
+ The AI will speak this message to the caller before hold music begins.
+ example: Please hold while I transfer you to a specialist.
+ default: Tell the user you are putting them on hold.
description: An object of parameters that will be utilized by the active command.
title: Hold call
CallRequest:
@@ -508,6 +523,14 @@ components:
example: calling.ai_unhold
params:
type: object
+ properties:
+ prompt:
+ type: string
+ description: |-
+ A system message added to the AI conversation when taking the caller off hold.
+ The AI will use this context when resuming the conversation.
+ example: The user has been connected to a specialist.
+ default: The user has been taken off hold.
description: An object of parameters that will be utilized by the active command.
title: Unhold call
CallUpdateCurrentCallRequest:
diff --git a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hangup.tsp b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hangup.tsp
new file mode 100644
index 000000000..15a22b799
--- /dev/null
+++ b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hangup.tsp
@@ -0,0 +1,6 @@
+@summary("HangupAction object")
+model HangupAction {
+ @doc("Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.")
+ @summary("hangup")
+ hangup: boolean;
+}
diff --git a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hold.tsp b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hold.tsp
new file mode 100644
index 000000000..c90e31540
--- /dev/null
+++ b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hold.tsp
@@ -0,0 +1,16 @@
+@summary("HoldAction object")
+model HoldAction {
+ @doc("""
+ Places the caller on hold while playing hold music (configured via params.hold_music).
+ During hold, speech detection is paused and the AI agent will not respond to the caller.
+ The value specifies the hold timeout in seconds.
+ Can be a number or an object with timeout property.
+ """)
+ @summary("hold")
+ @maxValue(900)
+ hold: int32 | {
+ @doc("The duration to hold the caller in seconds. Can be a number or an object with timeout property.")
+ @maxValue(900)
+ timeout?: int32 = 300;
+ };
+}
diff --git a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp
index 88b95bedf..d90c3b880 100644
--- a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp
+++ b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp
@@ -1,6 +1,8 @@
import "./change_context.tsp";
import "./change_step.tsp";
import "./context_switch.tsp";
+import "./hangup.tsp";
+import "./hold.tsp";
import "./playback_bg.tsp";
import "./say.tsp";
import "./set_global_data.tsp";
@@ -17,6 +19,8 @@ union Action {
ChangeContextAction,
ChangeStepAction,
ContextSwitchAction,
+ HangupAction,
+ HoldAction,
PlaybackBGAction,
SayAction,
SetGlobalDataAction,
diff --git a/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml b/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml
index 771678ef7..e17bb5b27 100644
--- a/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml
+++ b/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml
@@ -4887,6 +4887,8 @@ components:
- $ref: '#/components/schemas/ChangeContextAction'
- $ref: '#/components/schemas/ChangeStepAction'
- $ref: '#/components/schemas/ContextSwitchAction'
+ - $ref: '#/components/schemas/HangupAction'
+ - $ref: '#/components/schemas/HoldAction'
- $ref: '#/components/schemas/PlaybackBGAction'
- $ref: '#/components/schemas/SayAction'
- $ref: '#/components/schemas/SetGlobalDataAction'
@@ -7911,6 +7913,41 @@ components:
message: The addresses must belong to the project
attribute: allowed_addresses
url: https://developer.signalwire.com/rest/signalwire-rest/overview/error-codes#field-must-belong-to-project
+ HangupAction:
+ type: object
+ required:
+ - hangup
+ properties:
+ hangup:
+ type: boolean
+ description: Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.
+ title: hangup
+ title: HangupAction object
+ HoldAction:
+ type: object
+ required:
+ - hold
+ properties:
+ hold:
+ anyOf:
+ - type: integer
+ format: int32
+ - type: object
+ properties:
+ timeout:
+ type: integer
+ format: int32
+ maximum: 900
+ description: The duration to hold the caller in seconds.
+ default: 300
+ maximum: 900
+ description: |-
+ Places the caller on hold while playing hold music (configured via params.hold_music).
+ During hold, speech detection is paused and the AI agent will not respond to the caller.
+ The value specifies the hold timeout in seconds.
+ Can be a number or an object with timeout property.
+ title: hold
+ title: HoldAction object
IntegerOrZero:
type: integer
minimum: 10000
diff --git a/specs/swml/Methods/ai/swaig/functions/data_map/actions/hangup.tsp b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hangup.tsp
new file mode 100644
index 000000000..ad1252600
--- /dev/null
+++ b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hangup.tsp
@@ -0,0 +1,6 @@
+@summary("HangupAction object")
+model HangupAction {
+ @doc("Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.")
+ @summary("hangup")
+ hangup: boolean | SWMLVar;
+}
diff --git a/specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp
new file mode 100644
index 000000000..c90e31540
--- /dev/null
+++ b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp
@@ -0,0 +1,16 @@
+@summary("HoldAction object")
+model HoldAction {
+ @doc("""
+ Places the caller on hold while playing hold music (configured via params.hold_music).
+ During hold, speech detection is paused and the AI agent will not respond to the caller.
+ The value specifies the hold timeout in seconds.
+ Can be a number or an object with timeout property.
+ """)
+ @summary("hold")
+ @maxValue(900)
+ hold: int32 | {
+ @doc("The duration to hold the caller in seconds. Can be a number or an object with timeout property.")
+ @maxValue(900)
+ timeout?: int32 = 300;
+ };
+}
diff --git a/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp b/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp
index 157e623d4..f3ba197eb 100644
--- a/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp
+++ b/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp
@@ -2,6 +2,8 @@ import "./swml.tsp";
import "./change_context.tsp";
import "./change_step.tsp";
import "./context_switch.tsp";
+import "./hangup.tsp";
+import "./hold.tsp";
import "./playback_bg.tsp";
import "./say.tsp";
import "./set_global_data.tsp";
@@ -19,6 +21,8 @@ union Action {
ChangeContextAction,
ChangeStepAction,
ContextSwitchAction,
+ HangupAction,
+ HoldAction,
PlaybackBGAction,
SayAction,
SetGlobalDataAction,
diff --git a/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json b/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json
index edd1d318e..247c359c2 100644
--- a/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json
+++ b/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json
@@ -8795,6 +8795,12 @@
{
"$ref": "#/$defs/ContextSwitchAction"
},
+ {
+ "$ref": "#/$defs/HangupAction"
+ },
+ {
+ "$ref": "#/$defs/HoldAction"
+ },
{
"$ref": "#/$defs/PlaybackBGAction"
},
@@ -9065,6 +9071,69 @@
},
"title": "ContextSwitchAction object"
},
+ "HangupAction": {
+ "type": "object",
+ "properties": {
+ "hangup": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "$ref": "#/$defs/SWMLVar"
+ }
+ ],
+ "description": "Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.",
+ "title": "hangup"
+ }
+ },
+ "required": [
+ "hangup"
+ ],
+ "unevaluatedProperties": {
+ "not": {}
+ },
+ "title": "HangupAction object"
+ },
+ "HoldAction": {
+ "type": "object",
+ "properties": {
+ "hold": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "minimum": -2147483648,
+ "maximum": 2147483647
+ },
+ {
+ "type": "object",
+ "properties": {
+ "timeout": {
+ "type": "integer",
+ "minimum": -2147483648,
+ "maximum": 900,
+ "default": 300,
+ "description": "The duration to hold the caller in seconds."
+ }
+ },
+ "unevaluatedProperties": {
+ "not": {}
+ }
+ }
+ ],
+ "maximum": 900,
+ "description": "Places the caller on hold while playing hold music (configured via params.hold_music).\nDuring hold, speech detection is paused and the AI agent will not respond to the caller.\nThe value specifies the hold timeout in seconds.\nCan be a number or an object with timeout property.",
+ "title": "hold"
+ }
+ },
+ "required": [
+ "hold"
+ ],
+ "unevaluatedProperties": {
+ "not": {}
+ },
+ "title": "HoldAction object"
+ },
"PlaybackBGAction": {
"type": "object",
"properties": {
diff --git a/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx b/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx
index 74fdf1049..9b90132ef 100644
--- a/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx
+++ b/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx
@@ -28,6 +28,42 @@ import APIField from "@site/src/components/APIField";
Whether to stop the conversation.
+
+ Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.
+
+
+
+ Places the caller on hold while playing hold music (configured via the [`params.hold_music`](/swml/methods/ai/params/hold_music) parameter).
+ During hold, speech detection is paused and the AI agent will not respond to the caller.
+
+ The value specifies the hold timeout in seconds. Can be:
+ - An integer (e.g., `120` for 120 seconds)
+ - An object with a `timeout` property
+
+ Default timeout is `300` seconds (5 minutes). Maximum timeout is `900` seconds (15 minutes).
+
+ :::note Unholding a call
+ There is no `unhold` SWAIG action because the AI agent is inactive during hold and cannot process actions.
+ To take a caller off hold, either:
+ - Let the hold timeout expire (the AI will automatically resume with a default message), or
+ - Use the [Calling API `ai_unhold` command](/rest/signalwire-rest/endpoints/calling/call-commands) to programmatically unhold the call with a custom prompt.
+ :::
+
+
+
+ The duration to hold the caller in seconds. Maximum is `900` seconds (15 minutes).
+
+