Skip to content

New optional parameter custom_variables on REST Call Create and REST Message Create #339

@cassieemb

Description

@cassieemb

references https://github.com/signalwire/cloud-product/issues/18113

Background

Customers can create outbound RELAY messages using the api/messaging/messages API, and outbound SWML calls using the api/calling/calls API.

What Changed?

Customers can now pass a custom_variables object during the request for both endpoints in order to make them available during later lifecycle events.

Outbound Messages

When an outbound message request contains status_callback and custom_variables, the custom_variables will be appended to the callback event body.

Request:

curl --location 'https://SPACE.signalwire.com/api/messaging/messages' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic l' \
--data '{
    "from": "+12223334444",
    "to": "+12223334445",
    "body": "[SignalWire Message]",
    "status_callback": "https://webhook.site/95fc84f8-95e3-46bc-a1a5-9d1fa6fab117",
    "custom_variables": {
        "id": "12345",
        "case_number": "54321"
    }
}'

Status Callback Event

{
  "id": "243ddb26-10e7-48e5-a518-a0edc283555d",
  "project_id": "243ddb26-10e7-48e5-a518-a0edc283555d",
  "status": "delivered",
   "to": "+12223334445",
   "from": "+12223334444",
  "body": "[SignalWire Message]",
  "number_of_segments": 1,
  "timestamp": "2026-05-29T16:35:57Z",
  "error_code": null,
  "error_message": null,
  "custom_variables": {
    "id": "12345",
    "case_number": "54321"
  }
}

Outbound SWML Calls

When an outbound call is placed with a SWML document, the custom_variables will be appended to the POST body when the call answers and the SWML document is fetched.

Request:

curl --location 'https://SPACE.signalwire.com/api/calling/calls' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic ' \
--data '{
    "command": "dial",
    "params": {
        "url": "https://path_to_swml_document.com",
        "from": "+12223334444",
        "to": "+12223334445",
        "status_url": "https://webhook.site/95fc84f8-95e3-46bc-a1a5-9d1fa6fab117",
        "custom_variables": {
            "id": "12345",
            "case_number": "54321"
        }
    }
}'

Webhook Event on Document Fetch

{
  "call": {
    "call_id": "8923fdbe-9d39-42b6-9af2-e69a1832eab3",
    "node_id": "8923fdbe-9d39-42b6-9af2-e69a1832eab3",
    "segment_id": "8923fdbe-9d39-42b6-9af2-e69a1832eab3",
    "call_state": "answered",
    "direction": "outbound",
    "type": "phone",
    "from": "+12223334444",
    "to": "+12223334445",
    "from_number": "+12223334444",
    "to_number": "+12223334445",
    "headers": [],
    "dial_winner": "true",
    "project_id": "243ddb26-10e7-48e5-a518-a0edc283555d",
    "space_id": "243ddb26-10e7-48e5-a518-a0edc283555d"
  },
  "vars": {},
  "envs": {
    "id": "12345",
    "case_number": "54321"
  }
}

Validations

Requirement Rule
Key format Keys must match ^[A-Za-z_][A-Za-z0-9_]*$ - they must start with a letter or underscore, and contain only letters, numbers, and underscores.
Reserved prefixes Keys cannot begin with signalwire_, sw_, rtc_, or internal_ (case-insensitive). These prefixes are reserved for internal use.
Maximum keys A maximum of 20 keys is allowed.
Value size Each value can be at most 1024 bytes.
Value type Values must be non-empty strings.

Case sensitivity

Variable keys are case-sensitive. Per-call variables take precedence over pre-provisioned user variables - but only when their keys match exactly, including case.

If the keys differ in case, they are treated as two distinct variables and both are retained. For example, if a pre-provisioned variable is named GREETING and a per-call variable is named greeting, both will be present in the resulting user variables.

Errors

We have a few new codes for these params:

Code Message
must_be_object must be an object of string key/value pairs
too_many_custom_variables must contain at most %{max} custom variables
invalid_custom_variable_name custom variable name %{name} must start with a letter or underscore and contain only letters, numbers, and underscores
reserved_custom_variable_name custom variable name %{name} uses a reserved prefix and cannot be set by the caller
invalid_custom_variable_value custom variable %{name} value must be a non-empty string
custom_variable_value_too_long custom variable %{name} value must be at most %{max} bytes

Also, there was a code the previously had two messages but the same code - one was general, and one was specific to messaging. This was causing conflicts, so the original insufficient_balance code will remain with the message "Insufficient account balance", and the messaging specific one was renamed.

Code Message
insufficient_balance_to_receive_message Insufficient Account Balance to receive message.

What needs updates?

https://signalwire.com/docs/apis/rest/calls/call-commands
https://signalwire.com/docs/apis/rest/messages/create-message
https://signalwire.com/docs/apis/error-codes#error-code-reference

Notes

This will roll out to production global on June 1st, barring any issues with the planned deployment.

Please feel free to reach out with any questions!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions