# Voice SDK Call Message Events

## Voice SDK Call Message Events Feature Overview

The Call Message Events feature allows your client-side and server-side applications to communicate via custom ("user-defined") messages during a Voice SDK call. The feature leverages the existing signaling connection, so you don't need to set up your own communication channel between your client-side and server-side applications.

Two Twilio REST API Resources are used for server-side implementation:

* The [UserDefinedMessage Resource](/docs/voice/api/userdefinedmessage-resource), which allows your server-side application to send messages to the Voice SDK end user during an active Call
* The [UserDefinedMessageSubscription Resource](/docs/voice/api/userdefinedmessagesubscription-resource), which allows your server-side application to subscribe to messages sent from the Voice SDK for an active Call

The JavaScript, iOS, Android, and React Native SDKs provide the following functionality for the client-side implementation of Call Message Events:

## JavaScript SDK

**Method**

[call.sendMessage()](/docs/voice/sdks/javascript/twiliocall#callsendmessagemessage)

**Events**

[Call messageSent event](/docs/voice/sdks/javascript/twiliocall#messagesent-event)

[Call messageReceived event](/docs/voice/sdks/javascript/twiliocall#messagereceived-event)

## iOS SDK

**Classes**

`TVOCallMessage`

`TVOCallMessageBuilder`

**Method**

`[TVOCall sendMessage:]`

**Callbacks**

`[TVOCallMessageDelegate call:didReceiveMessage:]`

`[TVOCallMessageDelegate call:didSendMessage:]`

`[TVOCallMessageDelegate call:didFailToSendMessage:]`

See the [iOS SDK API Reference documentation](https://twilio.github.io/twilio-voice-ios/docs/latest/index.html) for more information.

## Android SDK

**Classes**

[com.twilio.voice.CallMessage](https://sdk.twilio.com/android/voice/latest/docs/com/twilio/voice/CallMessage.html)

[com.twilio.voice.CallMessage.Builder](https://sdk.twilio.com/android/voice/latest/docs/com/twilio/voice/CallMessage.Builder.html)

**Methods**

[com.twilio.voice.Call.sendMessage(...)](https://sdk.twilio.com/android/voice/latest/docs/com/twilio/voice/Call.html#sendMessage\(com.twilio.voice.CallMessage\))

**Interface Callbacks**

[com.twilio.voice.Call.CallMessageListener.onMessageReceived(...)](https://sdk.twilio.com/android/voice/latest/docs/com/twilio/voice/Call.CallMessageListener.html#onMessageReceived\(java.lang.String,com.twilio.voice.CallMessage\))

[com.twilio.voice.Call.CallMessageListener.onMessageSent(...)](https://sdk.twilio.com/android/voice/latest/docs/com/twilio/voice/Call.CallMessageListener.html#onMessageSent\(java.lang.String,java.lang.String\))

[com.twilio.voice.Call.CallMessageListener.onMessageFailure(...)](https://sdk.twilio.com/android/voice/latest/docs/com/twilio/voice/Call.CallMessageListener.html#onMessageFailure\(java.lang.String,java.lang.String,com.twilio.voice.VoiceException\))

## React Native SDK

**Classes**

[CallMessage](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.incomingcallmessage_class.md)

[OutgoingCallMessage](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.outgoingcallmessage_class.md)

**Methods**

[call.sendMessage](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.call_class.sendmessage_method.md)

[callInvite.sendMessage](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.callinvite_class.sendmessage_method.md)

**Events**

[Call messageReceived event](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.call_interface.addlistener_7_methodsignature.md)

[CallInvite messageReceived event](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.callinvite_interface.addlistener_4_methodsignature.md)

[OutgoingCallMessage messageSent event](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.outgoingcallmessage_interface.addlistener_1_methodsignature.md)

[OutgoingCallMessage messageError event](https://github.com/twilio/twilio-voice-react-native/blob/latest/docs/api/voice-react-native-sdk.outgoingcallmessage_interface.addlistener_methodsignature.md)

### Requirements

In order to implement the Call Message Events feature, you must use supported versions of the SDKs.

| Client-Side SDK        | Minimum Version Required |
| ---------------------- | ------------------------ |
| Voice JavaScript SDK   | v2.2.0                   |
| Voice iOS SDK          | v6.5.0                   |
| Voice Android SDK      | v6.4.0                   |
| Voice React Native SDK | v1.0.0                   |

| SDK        | Minimum Version Required |
| ---------- | ------------------------ |
| Node.js    | v3.83.1                  |
| Java       | v9.1.1                   |
| C#         | v5.81.1                  |
| Python     | v7.15.1                  |
| PHP        | v6.43.1                  |
| Go         | v1.1.1                   |
| Twilio CLI | v5.2.2                   |

### A note on "active" Calls

The Call Message Events feature works only for active Calls.

**Client side**

From the perspective of the SDK, a Call is active when both the signaling and media connections are established.

Select language/platform below to see how to active Calls are defined in the SDK.

## JavaScript SDK

The Call is active and ready for sending and receiving messages when the Call instance's status is `"open"` or `"ringing"`.

The status of the Call is retrieved via the [call.status() method](/docs/voice/sdks/javascript/twiliocall#callstatus).

The [Call instance's accept event](/docs/voice/sdks/javascript/twiliocall#accept-event) is emitted when the Call state transitions to `open`.

The Call instance's ringing event is emitted when the Call state transitions to `ringing`.

## iOS SDK

A Call is active and ready for sending and receiving messages when the `TVOCallState` is `TVOCallStateConnected `or` TVOCallStateRinging`.

The Call's state is returned via the `TVOCallState` property.

The [`[TVOCallDelegate callDidConnect:]`](https://twilio.github.io/twilio-voice-ios/docs/latest/Protocols/TVOCallDelegate.html#//api/name/callDidConnect:) callback is emitted when the Call state transitions to `TVOCallStateConnected`.

The [`[TVOCallDelegate callDidStartRinging:]`](https://twilio.github.io/twilio-voice-ios/docs/latest/Protocols/TVOCallDelegate.html#//api/name/callDidConnect:) callback is emitted when the Call state transitions to `TVOCallStateRinging`.

## Android SDK

A Call is active and ready for sending and receiving messages when the `Call.State` is `State.CONNECTED` or `State.RINGING`.

The Call's state is returned via the `Call.getState()` method.

The `Call.Listener.onConnected(...)` callback is emitted when the Call state transitions to `State.CONNECTED`.

The `Call.Listener.onRinging(...)` callback is emitted when the Call state transitions to `State.RINGING`.

## React Native SDK

The Call is active and ready for sending and receiving messages when the `Call.State` is `Call.State.Connected` or `Call.State.Ringing`.

The Call's state is returned via the `Call.getState()` method.

The Call event `Call.Event.Connected` is emitted when the Call state transitions to `Call.State.Connected`.

The Call event `Call.Event.Ringing` is emitted when the Call state transitions to `Call.State.Ringing`.

**Server side**

From the server side perspective, an "active" Call is a [Call Resource](/docs/voice/api/call-resource) with a `CallStatus` value of either `in-progress` or `ringing`.

The status for a Call Resource can be retrieved from the body of status callback requests or by fetching a Call Resource via API.

## Send messages from server, receive messages in the SDK

The general flow of sending a message from the server side to the SDK is as follows:

1. An SDK end user answers or places a Call and the Call is currently active.
2. The server-side application makes a `POST` request to the Call's [UserDefinedMessages endpoint](/docs/voice/api/userdefinedmessage-resource). This request contains the message to be sent.
3. The SDK receives the message.

### Required setup for server to SDK messaging

#### Prepare your server-side application to send messages to the SDK

You must have some way of retrieving the Call SID on your server side. One way to do this is with the `statusCallback` and `statusCallbackEvent` attributes in your [\<Client>](/docs/voice/twiml/client#attributes-status-callback) and [\<Number>](/docs/voice/twiml/number#attributes-status-callback) TwiML, in conjunction with an endpoint that handles status callback requests from Twilio.

#### Prepare your client-side application to receive messages

Add logic to your client-side application that handles incoming messages.

Select your Voice SDK language/platform below to see an example of receiving messages in the SDK.

## JavaScript SDK

```javascript
call.on("messageReceived", (message) => {
  console.log(JSON.stringify(message.content));
  //the voiceEventSid can be used for tracking the message
  console.log('voiceEventSid: ', message.voiceEventSid);
})
```

## iOS SDK

```swift
extension ViewController: CallMessageDelegate {

    func callDidReceiveMessage(call: Call, message callMessage: CallMessage) {
        NSLog("Call message received. Message: (callMessage.content)")
    }

}
```

## Android SDK

```java
class MyCallMessageListener implements Call.CallMessageListener {
   @Override
   public void onMessageReceived(final CallMessage callMesssage) {
      Log.d("[debug]", "Call message received. Message: " + callMessage.getContent());
   }
   @Override
   public void onMessageSent(final String voiceEventSID) {
      Log.d("[debug]", "Call message sent. Message Id: " + voiceEventSID);
   }
   @Override
   public void onMessageFailure(final String voiceEventSID, final VoiceException error) {
      Log.d("[debug]", "Call message failure. Message id: " +voiceEventSID + " error: " + error.getMessage());
   }
}
```

## React Native SDK

```typescript
call.addListener(Call.Event.MessageReceived, (message: CallMessage) => {
  console.log(JSON.stringify(message.getContent()))
  //the voiceEventSid can be used for tracking the message
  console.log('voiceEventSid: ', message.getSid());
});
```

#### Send a message from the server to the SDK

Once a Call is active, send a message by sending a `POST` request to the Call's [UserDefinedMessages endpoint](/docs/voice/api/userdefinedmessage-resource). The message content is passed in the `Content` parameter as a JSON string.

Send a message to the SDK

```js
// Download the helper library from https://www.twilio.com/docs/node/install
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);

async function createUserDefinedMessage() {
  const userDefinedMessage = await client
    .calls("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
    .userDefinedMessages.create({
      content: JSON.stringify({ key1: "Hello from the server side." }),
    });

  console.log(userDefinedMessage.accountSid);
}

createUserDefinedMessage();
```

```python
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client
import json

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
client = Client(account_sid, auth_token)

user_defined_message = client.calls(
    "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
).user_defined_messages.create(
    content=json.dumps({"key1": "Hello from the server side."})
)

print(user_defined_message.account_sid)
```

```csharp
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Api.V2010.Account.Call;
using System.Threading.Tasks;
using System.Collections.Generic;
using Newtonsoft.Json;

class Program {
    public static async Task Main(string[] args) {
        // Find your Account SID and Auth Token at twilio.com/console
        // and set the environment variables. See http://twil.io/secure
        string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
        string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");

        TwilioClient.Init(accountSid, authToken);

        var userDefinedMessage = await UserDefinedMessageResource.CreateAsync(
            content: JsonConvert.SerializeObject(
                new Dictionary<string, Object>() { { "key1", "Hello from the server side." } },
                Formatting.Indented),
            pathCallSid: "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

        Console.WriteLine(userDefinedMessage.AccountSid);
    }
}
```

```java
// Install the Java helper library from twilio.com/docs/java/install

import java.util.HashMap;
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.call.UserDefinedMessage;
import org.json.JSONObject;

public class Example {
    // Find your Account SID and Auth Token at twilio.com/console
    // and set the environment variables. See http://twil.io/secure
    public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
    public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        UserDefinedMessage userDefinedMessage =
            UserDefinedMessage
                .creator("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", new JSONObject(new HashMap<String, Object>() {
                    {
                        put("key1", "Hello from the server side.");
                    }
                }).toString())
                .create();

        System.out.println(userDefinedMessage.getAccountSid());
    }
}
```

```go
// Download the helper library from https://www.twilio.com/docs/go/install
package main

import (
	"encoding/json"
	"fmt"
	"github.com/twilio/twilio-go"
	api "github.com/twilio/twilio-go/rest/api/v2010"
	"os"
)

func main() {
	// Find your Account SID and Auth Token at twilio.com/console
	// and set the environment variables. See http://twil.io/secure
	// Make sure TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN exists in your environment
	client := twilio.NewRestClient()

	Content, ContentError := json.Marshal(map[string]interface{}{
		"key1": "Hello from the server side.",
	})

	if ContentError != nil {
		fmt.Println(ContentError)
		os.Exit(1)
	}

	params := &api.CreateUserDefinedMessageParams{}
	params.SetContent(string(Content))

	resp, err := client.Api.CreateUserDefinedMessage("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		params)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	} else {
		if resp.AccountSid != nil {
			fmt.Println(*resp.AccountSid)
		} else {
			fmt.Println(resp.AccountSid)
		}
	}
}
```

```php
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once "/path/to/vendor/autoload.php";

use Twilio\Rest\Client;

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);

$user_defined_message = $twilio
    ->calls("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
    ->userDefinedMessages->create(
        json_encode([
            "key1" => "Hello from the server side.",
        ]) // Content
    );

print $user_defined_message->accountSid;
```

```ruby
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'twilio-ruby'

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']
@client = Twilio::REST::Client.new(account_sid, auth_token)

user_defined_message = @client
                       .api
                       .v2010
                       .calls('CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
                       .user_defined_messages
                       .create(
                         content: {
                             'key1' => 'Hello from the server side.'
                           }.to_json
                       )

puts user_defined_message.account_sid
```

```bash
# Install the twilio-cli from https://twil.io/cli

twilio api:core:calls:user-defined-messages:create \
   --call-sid CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
   --content "{\"key1\":\"Hello from the server side.\"}"
```

```bash
CONTENT_OBJ=$(cat << EOF
{
  "key1": "Hello from the server side."
}
EOF
)
curl -X POST "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessages.json" \
--data-urlencode "Content=$CONTENT_OBJ" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
```

```json
{
  "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "call_sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "sid": "KXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "date_created": "Wed, 18 Dec 2019 20:02:01 +0000"
}
```

> \[!NOTE]
>
> Be sure you're using the correct Call SID when creating a subscription.
>
> If the SDK end user (the recipient of the message) made an **outgoing** call, you must subscribe to the **parent** Call SID.
>
> If the SDK end user (the recipient of the message) accepted an **incoming** call, you must subscribe to the **child** Call SID.
>
> Learn more about Call legs and the SDKs on the [Voice SDK Overview page](/docs/voice/sdks#call-legs-with-voice-sdk-calls).

#### Receive messages in the SDK

Provided that the message was sent successfully from the server side, the SDK will receive the message. [See the code samples above](#prepare-your-client-side-application-to-receive-messages) for SDK-specific handling of incoming messages.

## Send messages from the SDK to the server side

In order to receive messages on your server from the SDK, you need to set up a subscription to the Call's messages. In the subscription, you specify where Twilio should send the messages. Once a subscription is created, the SDK end-user can send messages that Twilio will then send in an HTTP request to your server-side application.

The general flow of sending a message from the SDK to the server side is as follows:

1. An SDK end user answers or places a Call and the Call is currently active.
2. The server-side application makes a `POST` request to the Call's [UserDefinedMessageSubscriptions endpoint](/docs/voice/api/userdefinedmessagesubscription-resource).
3. The `call.sendMessage()` method is invoked in the SDK.
4. The endpoint specified in the UserDefinedMessageSubscription request receives the message from Twilio.

### Required setup for SDK to server messaging

#### Prepare your server-side application to receive messages from the SDK

* Before you can receive any messages from the SDK, you need to set up an HTTP endpoint where Twilio will send messages. Your endpoint must be able to accept application/json. This endpoint's URL is used as the `Callback` parameter when subscribing to a Call's messages.
* You must have some way of retrieving the Call SID on your server side. One way to do this is with the `statusCallback` and `statusCallbackEvent` attributes in your [\<Client>](/docs/voice/twiml/client#attributes-status-callback) and [\<Number>](/docs/voice/twiml/number#attributes-status-callback) TwiML, in conjunction with an endpoint that handles status callback requests from Twilio.

#### Prepare your client-side application to send messages

Add logic to your client-side application that:

* constructs a valid message object
* invokes the `call.sendMessage()` method during an active call
* handles the success/failure of a message sending attempt

Select your Voice SDK language/platform below to see an example of sending a message from the SDK to the server side.

## JavaScript SDK

```javascript
// Errors related to Call Message Events are emitted by the Device instance.
device.on("error", function (twilioError) {
  console.error(twilioError);
});

// a Call is active

// add listener for 'messageSent' event
call.on("messageSent", () => {
  console.log("Message sent.")
});

// create the Call Message
const callMessage = { 
  content: { key1: 'This is a messsage from the parent call' },
  messageType: 'user-defined-message', 
  contentType: "application/json"
}

// send the message
// the voiceEventSid can be used for tracking the message
sendMessageButton.onclick = () => {
  console.log('Sending message.')
  const voiceEventSid = call.sendMessage(callMessage)
}
```

## iOS SDK

```swift
let call = TwilioVoiceSDK.connect(options: connectOptions, delegate: self)

// Wait for a call to be connected

// Construct the message object
let message = "{ \"key1\": \"This is a message from the SDK\"}"
let callMessage = CallMessage(content: message)

// Send the message
// voiceEventSid can be used for tracking the message
let voiceEventSid = call.sendMessage(callMessage)

// Handle success/failure
extension ViewController: CallMessageDelegate {
    func callDidSendMessage(call: Call, voiceEventSid: String) {
        NSLog("Call message sent. Voice Event SID: (voiceEventSid)")
    }

    func callDidFailToSendMessage(call: Call, voiceEventSid: String, error: Error) {
        NSLog("Failed to send call message. Voice Event SID: (voiceEventSid). Error: (error.localizedDescription)")
    }
}
```

## Android SDK

```java
ConnectOptions cxnOptions = new ConnectOptions.Builder(accessToken)
  .callMessageListener(new Call.CallMessageListener() {
    @Override
    public void onMessageReceived(final CallMessage callMesssage) {
      Log.d("[debug]", "Call message received. Message: " + callMessage.getContent());
    }
    @Override
    public void onMessageSent(final String voiceEventSID) {
      Log.d("[debug]", "Call message sent. Message Id: " + voiceEventSID);
    }
    @Override
    public void onMessageFailure(final String voiceEventSID, final VoiceException error) {
      Log.d("[debug]", "Call message failure. Message id: " +voiceEventSID + " error: " + error.getMessage());
    }
  })
  .params(params)
  .build();
Call call = voice.connect(myActivityContext, cxnOptions, myCallListener);

// Wait for call to be connected
...
// Construct call message
final CallMessage callMessage = (new CallMessage.Builder(CallMessage.MessageType.UserDefinedMessage))
  .contentType("application/json")
  .content((new JSONObject())
    .put("test_field", "test")
    .toString())
  .build();
...
// Send message
call.sendMessage(callMessage);
```

## React Native SDK

```typescript
// create the Call Message
const message = new CallMessage({
  // Note: content must match contentType
  content: { key1: 'This is a message from the parent call' },
  contentType: CallMessage.ContentType.ApplicationJson,
  messageType: CallMessage.MessageType.UserDefinedMessage
});

// send the message 
const outgoingCallMessage: OutgoingCallMessage = await call.sendMessage(message);

// the voiceEventSid can be used for tracking the message
const voiceEventSID = outgoingCallMessage.getSid()

// add listener for 'messageFailure' event
outgoingCallMessage.addListener(OutgoingCallMessage.Event.Failure, (error) => {
  // outgoingCallMessage failed, handle error
});

// add listener for 'messageSent' event
outgoingCallMessage.addListener(OutgoingCallMessage.Event.Sent, () => {
    // outgoingCallMessage sent
});
```

You can only send messages during an active Call. If you have any UI elements that your SDK end user interacts with (e.g. a "Send Message" button), make sure that sending messages is only enabled during an active Call.

#### Subscribe to an active Call's messages

Once a Call is active, your server-side must set up a subscription to a Call's messages by making a `POST` request to the Call's [UserDefinedMessageSubscription Resource](/docs/voice/api/userdefinedmessagesubscription-resource).

The `Callback` parameter specifies your endpoint that will receive messages from Twilio.

Subscribe to a Call's Messages

```js
// Download the helper library from https://www.twilio.com/docs/node/install
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);

async function createUserDefinedMessageSubscription() {
  const userDefinedMessageSubscription = await client
    .calls("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
    .userDefinedMessageSubscriptions.create({
      callback:
        "https://www.example.com/your-endpoint-that-can-receive-messages",
      method: "POST",
    });

  console.log(userDefinedMessageSubscription.accountSid);
}

createUserDefinedMessageSubscription();
```

```python
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
client = Client(account_sid, auth_token)

user_defined_message_subscription = client.calls(
    "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
).user_defined_message_subscriptions.create(
    callback="https://www.example.com/your-endpoint-that-can-receive-messages",
    method="POST",
)

print(user_defined_message_subscription.account_sid)
```

```csharp
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Api.V2010.Account.Call;
using System.Threading.Tasks;

class Program {
    public static async Task Main(string[] args) {
        // Find your Account SID and Auth Token at twilio.com/console
        // and set the environment variables. See http://twil.io/secure
        string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
        string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");

        TwilioClient.Init(accountSid, authToken);

        var userDefinedMessageSubscription =
            await UserDefinedMessageSubscriptionResource.CreateAsync(
                callback: new Uri(
                    "https://www.example.com/your-endpoint-that-can-receive-messages"),
                method: Twilio.Http.HttpMethod.Post,
                pathCallSid: "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

        Console.WriteLine(userDefinedMessageSubscription.AccountSid);
    }
}
```

```java
// Install the Java helper library from twilio.com/docs/java/install

import java.net.URI;
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.call.UserDefinedMessageSubscription;
import com.twilio.http.HttpMethod;

public class Example {
    // Find your Account SID and Auth Token at twilio.com/console
    // and set the environment variables. See http://twil.io/secure
    public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
    public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        UserDefinedMessageSubscription userDefinedMessageSubscription =
            UserDefinedMessageSubscription
                .creator("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    URI.create("https://www.example.com/your-endpoint-that-can-receive-messages"))
                .setMethod(HttpMethod.POST)
                .create();

        System.out.println(userDefinedMessageSubscription.getAccountSid());
    }
}
```

```go
// Download the helper library from https://www.twilio.com/docs/go/install
package main

import (
	"fmt"
	"github.com/twilio/twilio-go"
	api "github.com/twilio/twilio-go/rest/api/v2010"
	"os"
)

func main() {
	// Find your Account SID and Auth Token at twilio.com/console
	// and set the environment variables. See http://twil.io/secure
	// Make sure TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN exists in your environment
	client := twilio.NewRestClient()

	params := &api.CreateUserDefinedMessageSubscriptionParams{}
	params.SetCallback("https://www.example.com/your-endpoint-that-can-receive-messages")
	params.SetMethod("POST")

	resp, err := client.Api.CreateUserDefinedMessageSubscription("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		params)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	} else {
		if resp.AccountSid != nil {
			fmt.Println(*resp.AccountSid)
		} else {
			fmt.Println(resp.AccountSid)
		}
	}
}
```

```php
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once "/path/to/vendor/autoload.php";

use Twilio\Rest\Client;

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);

$user_defined_message_subscription = $twilio
    ->calls("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
    ->userDefinedMessageSubscriptions->create(
        "https://www.example.com/your-endpoint-that-can-receive-messages", // Callback
        ["method" => "POST"]
    );

print $user_defined_message_subscription->accountSid;
```

```ruby
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'twilio-ruby'

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']
@client = Twilio::REST::Client.new(account_sid, auth_token)

user_defined_message_subscription = @client
                                    .api
                                    .v2010
                                    .calls('CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
                                    .user_defined_message_subscriptions
                                    .create(
                                      callback: 'https://www.example.com/your-endpoint-that-can-receive-messages',
                                      method: 'POST'
                                    )

puts user_defined_message_subscription.account_sid
```

```bash
# Install the twilio-cli from https://twil.io/cli

twilio api:core:calls:user-defined-message-subscriptions:create \
   --call-sid CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
   --callback https://www.example.com/your-endpoint-that-can-receive-messages \
   --method POST
```

```bash
curl -X POST "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessageSubscriptions.json" \
--data-urlencode "Callback=https://www.example.com/your-endpoint-that-can-receive-messages" \
--data-urlencode "Method=POST" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
```

```json
{
  "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "call_sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "sid": "ZYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "date_created": "Wed, 18 Dec 2019 20:02:01 +0000",
  "uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessageSubscriptions/ZYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json"
}
```

> \[!NOTE]
>
> Be sure you're using the correct Call SID when creating a subscription.
>
> If the SDK end user (who is sending messages that you wish to receive) made an **outgoing** call, you must subscribe to the **parent** Call SID.
>
> If the SDK end user (who is sending messages that you wish to receive) accepted an **incoming** call, you must subscribe to the **child** Call SID.
>
> Learn more about Call legs and the SDKs on the [Voice SDK Overview page](/docs/voice/sdks#call-legs-with-voice-sdk-calls).

#### Send a message from the SDK

Once a subscription has been set up, the SDK can now invoke the `call.sendMessage()` event.

#### Receive the message on the server side

If a subscription was created and then the SDK sent a message successfully, your `Callback` endpoint will receive the request from Twilio. The message from the SDK is contained in the `Content` property of the request.

See an example of the Twilio's request to the `Callback` endpoint below, followed by a description of the parameters in the request.

```bash
{
  ContentType: 'application/json',
  Content: '{"key1":"This is a messsage from the SDK"}',
  SequenceNumber: '1',
  CallSid: 'CA0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
  Timestamp: 'Fri, 2 Dec 2022 22:02:49 +0000',
  AccountSid: 'ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
  Sid: 'KXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
}
```

| Parameter      | Description                                                                            |
| -------------- | -------------------------------------------------------------------------------------- |
| ContentType    | The `Content-Type` of the request. (Currently, Twilio only supports application/json.) |
| Content        | The message sent from the SDK as a JSON string.                                        |
| SequenceNumber | The order in which the messages were sent, starting from 0.                            |
| CallSid        | The SID of the Call Resource this message is associated with                           |
| Timestamp      | The timestamp when Twilio sent this message, given as UTC in RFC 2822 format.          |
| AccountSid     | The Twilio Account SID associated with the message.                                    |
| Sid            | A unique identifier for this message. This can be used for internal logging/tracking.  |
