From efdc406f81b42fa5720713fb962ab3292c41dff4 Mon Sep 17 00:00:00 2001 From: Devon-White Date: Thu, 31 Jul 2025 12:05:13 -0400 Subject: [PATCH 1/4] Add status_url & status_events. Add externalDocs, tag metadata, and info in spec. --- .../calling-api/calls/const.tsp | 1 + .../calling-api/calls/main.tsp | 6 +- .../calling-api/calls/models/core.tsp | 46 ++++-- .../calling-api/calls/models/requests.tsp | 14 ++ specs/signalwire-rest/calling-api/main.tsp | 25 +++- specs/signalwire-rest/calling-api/tags.tsp | 11 ++ .../@typespec/openapi3/openapi.yaml | 134 ++++++++++++++++-- 7 files changed, 202 insertions(+), 35 deletions(-) create mode 100644 specs/signalwire-rest/calling-api/calls/const.tsp create mode 100644 specs/signalwire-rest/calling-api/tags.tsp diff --git a/specs/signalwire-rest/calling-api/calls/const.tsp b/specs/signalwire-rest/calling-api/calls/const.tsp new file mode 100644 index 000000000..34a3893dc --- /dev/null +++ b/specs/signalwire-rest/calling-api/calls/const.tsp @@ -0,0 +1 @@ +import "../../_globally_shared/const.tsp"; diff --git a/specs/signalwire-rest/calling-api/calls/main.tsp b/specs/signalwire-rest/calling-api/calls/main.tsp index 59be619f4..e7366d590 100644 --- a/specs/signalwire-rest/calling-api/calls/main.tsp +++ b/specs/signalwire-rest/calling-api/calls/main.tsp @@ -21,7 +21,8 @@ namespace CallingAPI.Calls { } | StatusCode401 | StatusCode404 - | CallCreate422Error; + | CallCreate422Error | + StatusCode500; @summary("Update a Call") @doc("To update an existing call, you send a `PUT` request to the Call resource with a payload including a `command` and additional nested `params`.") @@ -55,6 +56,7 @@ namespace CallingAPI.Calls { } | StatusCode401 | StatusCode404 - | CallUpdate422Error; + | CallUpdate422Error | + StatusCode500; } } diff --git a/specs/signalwire-rest/calling-api/calls/models/core.tsp b/specs/signalwire-rest/calling-api/calls/models/core.tsp index 69f52b39a..ed1b4db95 100644 --- a/specs/signalwire-rest/calling-api/calls/models/core.tsp +++ b/specs/signalwire-rest/calling-api/calls/models/core.tsp @@ -1,14 +1,16 @@ +import "../const.tsp"; + model Call { @doc("The unique identifier of the call on SignalWire. This can be used to update the call programmatically.") - @example("3fa85f64-5717-4562-b3fc-2c963f66afa6") + @example("0e9c80d7-a149-4917-892d-420043709f45") id: string; @doc("The origin number or address.") - @example("sip:from-sip@example-112233445566.sip.signalwire.com") + @example("+12069708643") from: string; @doc("The destination number or address.") - @example("sip:from-sip@example-112233445567.sip.signalwire.com") + @example("+18048390497") to: string; @doc("The direction of the call.") @@ -20,33 +22,51 @@ model Call { status: "answered" | "queued" | "initiated" | "ringing" | "ending" | "ended"; @doc("The duration of the call in seconds.") - @example(60) - duration: integer; + @example(null) + duration: integer | null; @doc("The duration of the call in milliseconds.") - @example(60000) - duration_ms: integer; + @example(null) + duration_ms: integer | null; - @doc("The billable duration of the call in seconds.") - @example(60) - billable_duration: integer; + @doc("The billable duration of the call in milliseconds.") + @example(null) + billing_ms: integer | null; @doc("Source of this call.") @example("realtime_api") source: "realtime_api"; @doc("Type of this call.") - @example("relay_sip_call") + @example("relay_pstn_call") type: "relay_pstn_call" | "relay_sip_call" | "relay_webrtc_call"; + @doc("The URL associated with this call.") + @example(null) + url: string | null; + + @doc("Total charge for this call.") + @example(0) + charge: float64; + + @doc("The date and time when the call was created.") + @example(UTC_TIME_EXAMPLE) + created_at: utcDateTime; + + @doc("The parent call ID if this is a child call.") + @example(null) + parent_id: string | null; + @doc("Details on charges associated with this call.") - charge: ChargeDetails[]; + charge_details: ChargeDetails[]; } model ChargeDetails { @doc("Description for this charge.") + @example("Text to Speach") description: string; @doc("Charged amount.") - amount: integer; + @example(0.121176) + amount: float; } diff --git a/specs/signalwire-rest/calling-api/calls/models/requests.tsp b/specs/signalwire-rest/calling-api/calls/models/requests.tsp index 1d1a0ca2b..274f85d37 100644 --- a/specs/signalwire-rest/calling-api/calls/models/requests.tsp +++ b/specs/signalwire-rest/calling-api/calls/models/requests.tsp @@ -120,6 +120,20 @@ model CallCreateParamsBase { @doc("The Fallback URL to handle the call. This parameter allows you to specify a backup webhook or different route in your code containing SWML instructions for handling the call.") @example(CallFallbackURLExample) fallback_url?: string; + + @doc("A URL that will recieve status updates of the current call. Any call events defined in `status_events` will be delivered to the defined URL.") + @example("https://example.com/status_callback") + status_url?: url; + + @doc("The call events that will be monitored and sent to the `status_url` when active.") + @example(#["answered", "ended"]) + status_events?: ( + | "answered" + | "queued" + | "initiated" + | "ringing" + | "ending" + | "ended")[]; } @summary("Create call (URL)") diff --git a/specs/signalwire-rest/calling-api/main.tsp b/specs/signalwire-rest/calling-api/main.tsp index 4e78060a4..b7f619c57 100644 --- a/specs/signalwire-rest/calling-api/main.tsp +++ b/specs/signalwire-rest/calling-api/main.tsp @@ -1,21 +1,36 @@ import "@typespec/http"; +import "@typespec/openapi"; import "../types"; import "./calls"; +import "../_globally_shared/const.tsp"; +import "./tags.tsp"; using TypeSpec.Http; +using TypeSpec.OpenAPI; using Types.StatusCodes; +@tagMetadata(CALLS_TAG, CALLS_TAG_METADATA) +@externalDocs( + "https://developer.signalwire.com/rest/signalwire-rest/endpoints/calling", + "The Calling API holds a collection of endpoints that will help you create and manage calls." +) +@info(#{ + title: "Calling API", + version: "1.0.0", + contact: CONTACT_INFO, + license: LICENSE_INFO, + termsOfService: TERMS_OF_SERVICE, +}) @service(#{ title: "Calling API" }) @server( - "https://{space_name}.signalwire.com/api/calling", + "https://{space_name}.${SERVER_URL}/calling", "Endpoint", { + @doc(SERVER_URL_DESCRIPTION) + @example("example") space_name: string = "{Your_Space_Name}", } ) @useAuth(BasicAuth) -@doc(""" - API to create/manage SignalWire's Calls. - To create a new Call, you send a `POST` request to the Call resource with a payload including a `dial` command and additional nested `params`. - """) +@doc("API to create/manage SignalWire's Calls.") namespace CallingAPI; diff --git a/specs/signalwire-rest/calling-api/tags.tsp b/specs/signalwire-rest/calling-api/tags.tsp new file mode 100644 index 000000000..33293c788 --- /dev/null +++ b/specs/signalwire-rest/calling-api/tags.tsp @@ -0,0 +1,11 @@ +import "@typespec/openapi3"; + +const CALLS_TAG = "Calls"; + +const CALLS_TAG_METADATA = #{ + description: "Endpoints related to creating and managing calls", + externalDocs: #{ + url: "https://developer.signalwire.com/rest/signalwire-rest/endpoints/calling/calls", + description: "Developer documentation on Calling API Call endpoints", + }, +}; \ No newline at end of file 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 bef49cfb8..a8abdc027 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 @@ -1,12 +1,25 @@ openapi: 3.0.0 info: title: Calling API - description: |- - API to create/manage SignalWire's Calls. - To create a new Call, you send a `POST` request to the Call resource with a payload including a `dial` command and additional nested `params`. - version: 0.0.0 + version: 1.0.0 + contact: + name: SignalWire + url: https://support.signalwire.com/portal/en/newticket?departmentId=1029313000000006907&layoutId=1029313000000074011 + email: support@signalwire.com + license: + name: MIT + url: https://github.com/signalwire/docs/blob/main/LICENSE + termsOfService: https://signalwire.com/legal/signalwire-cloud-agreement + description: API to create/manage SignalWire's Calls. +externalDocs: + url: https://developer.signalwire.com/rest/signalwire-rest/endpoints/calling + description: The Calling API holds a collection of endpoints that will help you create and manage calls. tags: - name: Calls + description: Endpoints related to creating and managing calls + externalDocs: + url: https://developer.signalwire.com/rest/signalwire-rest/endpoints/calling/calls + description: Developer documentation on Calling API Call endpoints paths: /calls: post: @@ -39,6 +52,12 @@ paths: application/json: schema: $ref: '#/components/schemas/CallCreate422Error' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/Types.StatusCodes.StatusCode500' tags: - Calls requestBody: @@ -77,6 +96,12 @@ paths: application/json: schema: $ref: '#/components/schemas/CallUpdate422Error' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/Types.StatusCodes.StatusCode500' tags: - Calls requestBody: @@ -194,6 +219,26 @@ components: type: string description: The Fallback URL to handle the call. This parameter allows you to specify a backup webhook or different route in your code containing SWML instructions for handling the call. example: https://example.com/fallback + status_url: + type: string + format: uri + description: A URL that will recieve status updates of the current call. Any call events defined in `status_events` will be delivered to the defined URL. + example: https://example.com/status_callback + status_events: + type: array + items: + type: string + enum: + - answered + - queued + - initiated + - ringing + - ending + - ended + description: The call events that will be monitored and sent to the `status_url` when active. + example: + - answered + - ended swml: type: string description: Inline SWML, passed as a string, containing SWML instructions for handling the call. Either `url` or `swml` must be included for a new call. @@ -222,6 +267,26 @@ components: type: string description: The Fallback URL to handle the call. This parameter allows you to specify a backup webhook or different route in your code containing SWML instructions for handling the call. example: https://example.com/fallback + status_url: + type: string + format: uri + description: A URL that will recieve status updates of the current call. Any call events defined in `status_events` will be delivered to the defined URL. + example: https://example.com/status_callback + status_events: + type: array + items: + type: string + enum: + - answered + - queued + - initiated + - ringing + - ending + - ended + description: The call events that will be monitored and sent to the `status_url` when active. + example: + - answered + - ended url: type: string description: |- @@ -309,23 +374,27 @@ components: - status - duration - duration_ms - - billable_duration + - billing_ms - source - type + - url - charge + - created_at + - parent_id + - charge_details properties: id: type: string description: The unique identifier of the call on SignalWire. This can be used to update the call programmatically. - example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + example: 0e9c80d7-a149-4917-892d-420043709f45 from: type: string description: The origin number or address. - example: sip:from-sip@example-112233445566.sip.signalwire.com + example: '+12069708643' to: type: string description: The destination number or address. - example: sip:from-sip@example-112233445567.sip.signalwire.com + example: '+18048390497' direction: type: string enum: @@ -345,16 +414,19 @@ components: example: queued duration: type: integer + nullable: true description: The duration of the call in seconds. - example: 60 + example: null duration_ms: type: integer + nullable: true description: The duration of the call in milliseconds. - example: 60000 - billable_duration: + example: null + billing_ms: type: integer - description: The billable duration of the call in seconds. - example: 60 + nullable: true + description: The billable duration of the call in milliseconds. + example: null source: type: string enum: @@ -368,8 +440,28 @@ components: - relay_sip_call - relay_webrtc_call description: Type of this call. - example: relay_sip_call + example: relay_pstn_call + url: + type: string + nullable: true + description: The URL associated with this call. + example: null charge: + type: number + format: double + description: Total charge for this call. + example: 0 + created_at: + type: string + format: date-time + description: The date and time when the call was created. + example: '2024-05-06T12:20:00Z' + parent_id: + type: string + nullable: true + description: The parent call ID if this is a child call. + example: null + charge_details: type: array items: $ref: '#/components/schemas/ChargeDetails' @@ -520,9 +612,11 @@ components: description: type: string description: Description for this charge. + example: Text to Speach amount: - type: integer + type: number description: Charged amount. + example: 0.121176 Types.StatusCodes.StatusCode401: type: object required: @@ -565,6 +659,15 @@ components: url: type: string description: Link to developer resource for this error. + Types.StatusCodes.StatusCode500: + type: object + required: + - error + properties: + error: + type: string + enum: + - Internal Server Error UpdateCurrentCallRequest: oneOf: - $ref: '#/components/schemas/CallUpdateSWMLRequest' @@ -584,3 +687,4 @@ servers: variables: space_name: default: '{Your_Space_Name}' + description: The domain of the users SignalWire space. From 54950295e7f9cf89f405f15900f85eefa81da399 Mon Sep 17 00:00:00 2001 From: hey-august Date: Thu, 31 Jul 2025 19:05:48 -0400 Subject: [PATCH 2/4] spelling fix in `ChargeDetails` tsp model --- specs/signalwire-rest/calling-api/calls/models/core.tsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/signalwire-rest/calling-api/calls/models/core.tsp b/specs/signalwire-rest/calling-api/calls/models/core.tsp index ed1b4db95..79bb5956a 100644 --- a/specs/signalwire-rest/calling-api/calls/models/core.tsp +++ b/specs/signalwire-rest/calling-api/calls/models/core.tsp @@ -63,7 +63,7 @@ model Call { model ChargeDetails { @doc("Description for this charge.") - @example("Text to Speach") + @example("Text to Speech") description: string; @doc("Charged amount.") From cbb78e0cf2e6347da071915cafa552e80c1bef54 Mon Sep 17 00:00:00 2001 From: hey-august Date: Thu, 31 Jul 2025 19:27:29 -0400 Subject: [PATCH 3/4] grammar fix in `paramsDescription` in requests.tsp --- specs/signalwire-rest/calling-api/calls/models/requests.tsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/signalwire-rest/calling-api/calls/models/requests.tsp b/specs/signalwire-rest/calling-api/calls/models/requests.tsp index 274f85d37..129119750 100644 --- a/specs/signalwire-rest/calling-api/calls/models/requests.tsp +++ b/specs/signalwire-rest/calling-api/calls/models/requests.tsp @@ -16,7 +16,7 @@ const updateCommandDescription = "The `update` command is used to update a exist const uuidDescription = "The unique identifying ID of a existing call."; -const paramsDescription = "An object of parameters to that will be utilized by the active command."; +const paramsDescription = "An object of parameters that will be utilized by the active command."; alias CallCreateRequestAlias = CallCreateParamsURL | CallCreateParamsSWML; From ac4c2b31685aa65f1636fcc869b017f3bca51bbd Mon Sep 17 00:00:00 2001 From: hey-august Date: Thu, 31 Jul 2025 20:08:59 -0400 Subject: [PATCH 4/4] spec updates --- specs/signalwire-rest/calling-api/calls/main.tsp | 8 ++++---- specs/signalwire-rest/calling-api/tags.tsp | 2 +- .../tsp-output/@typespec/openapi3/openapi.yaml | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/specs/signalwire-rest/calling-api/calls/main.tsp b/specs/signalwire-rest/calling-api/calls/main.tsp index e7366d590..c4ed754f2 100644 --- a/specs/signalwire-rest/calling-api/calls/main.tsp +++ b/specs/signalwire-rest/calling-api/calls/main.tsp @@ -21,8 +21,8 @@ namespace CallingAPI.Calls { } | StatusCode401 | StatusCode404 - | CallCreate422Error | - StatusCode500; + | CallCreate422Error + | StatusCode500; @summary("Update a Call") @doc("To update an existing call, you send a `PUT` request to the Call resource with a payload including a `command` and additional nested `params`.") @@ -56,7 +56,7 @@ namespace CallingAPI.Calls { } | StatusCode401 | StatusCode404 - | CallUpdate422Error | - StatusCode500; + | CallUpdate422Error + | StatusCode500; } } diff --git a/specs/signalwire-rest/calling-api/tags.tsp b/specs/signalwire-rest/calling-api/tags.tsp index 33293c788..d77249969 100644 --- a/specs/signalwire-rest/calling-api/tags.tsp +++ b/specs/signalwire-rest/calling-api/tags.tsp @@ -8,4 +8,4 @@ const CALLS_TAG_METADATA = #{ url: "https://developer.signalwire.com/rest/signalwire-rest/endpoints/calling/calls", description: "Developer documentation on Calling API Call endpoints", }, -}; \ No newline at end of file +}; 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 a8abdc027..8c707e659 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 @@ -178,7 +178,7 @@ components: required: - role - message_text - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Inject AI message CallCreate422Error: type: object @@ -310,7 +310,7 @@ components: anyOf: - $ref: '#/components/schemas/CallCreateParamsURL' - $ref: '#/components/schemas/CallCreateParamsSWML' - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Create call CallHangupRequest: type: object @@ -340,7 +340,7 @@ components: - busy description: Set the reason why the call was hung up. example: hangup - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Hangup call CallHoldRequest: type: object @@ -362,7 +362,7 @@ components: example: calling.ai_hold params: type: object - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Hold call CallResponse: type: object @@ -486,7 +486,7 @@ components: example: calling.ai_unhold params: type: object - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Unhold call CallUpdate422Error: type: object @@ -584,7 +584,7 @@ components: params: allOf: - $ref: '#/components/schemas/CallUpdateParamsSWML' - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Update call (SWML) CallUpdateURLRequest: type: object @@ -601,7 +601,7 @@ components: params: allOf: - $ref: '#/components/schemas/CallUpdateParamsURL' - description: An object of parameters to that will be utilized by the active command. + description: An object of parameters that will be utilized by the active command. title: Update call (URL) ChargeDetails: type: object @@ -612,7 +612,7 @@ components: description: type: string description: Description for this charge. - example: Text to Speach + example: Text to Speech amount: type: number description: Charged amount.