> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# xAI Voice Agents Integration

> Route calls from a Plivo phone number to an xAI Voice Agent over Plivo SIP Trunking.

Build a Grok voice-agent in [xAI Voice Agents](https://console.x.ai/) and have it answer calls to your Plivo phone number. Plivo sends each call over an inbound SIP trunk to xAI, where the agent is hosted, so you don't run any server.

***

## How the integration works

<div className="sipflow sipflow--vertical">
  <div className="sipflow__head">
    <span>Call flow</span>

    <span className="sipflow__head-right">
      <span className="sipflow__led" aria-hidden="true" />

      Plivo SIP Trunking · xAI
    </span>
  </div>

  <ol className="sipflow__body">
    <li>
      <div className="sipflow__node">
        <span className="sipflow__node-body">
          <span className="sipflow__title">Caller</span>
          <span className="sipflow__sub">Dials your Plivo phone number</span>
        </span>
      </div>

      <div className="sipflow__link" aria-hidden="true">
        <span className="sipflow__rail" />

        <span className="sipflow__arrow" />
      </div>
    </li>

    <li>
      <div className="sipflow__node">
        <span className="sipflow__node-body">
          <span className="sipflow__title">Plivo inbound SIP trunk</span>
          <span className="sipflow__sub">Primary URI: sip.voice.x.ai</span>
        </span>
      </div>

      <div className="sipflow__link">
        <span className="sipflow__rail" aria-hidden="true" />

        <span className="sipflow__edge-label">SIP over TLS</span>

        <span className="sipflow__arrow" aria-hidden="true" />
      </div>
    </li>

    <li>
      <div className="sipflow__node">
        <span className="sipflow__node-body">
          <span className="sipflow__title">xAI</span>
          <span className="sipflow__sub">Checks Plivo's IP address or SIP digest credentials, then matches the dialed number</span>
        </span>
      </div>

      <div className="sipflow__link" aria-hidden="true">
        <span className="sipflow__rail" />

        <span className="sipflow__arrow" />
      </div>
    </li>

    <li>
      <div className="sipflow__node">
        <span className="sipflow__node-body">
          <span className="sipflow__title">xAI Voice Agent</span>
          <span className="sipflow__sub">Answers with its welcome message</span>
        </span>
      </div>
    </li>
  </ol>
</div>

| Step | What happens                                                                                                            | Where you configure it                     |
| ---- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| 1    | A caller dials your Plivo phone number.                                                                                 | Plivo number connected to an inbound trunk |
| 2    | Plivo sends the call over the inbound SIP trunk to `sip.voice.x.ai` using TLS.                                          | Plivo inbound trunk                        |
| 3    | xAI accepts the call from Plivo's IP addresses (or SIP digest credentials) and matches the dialed number to your agent. | Phone number in your xAI agent             |
| 4    | The agent answers with its saved instructions, voice, and welcome message.                                              | xAI Console → **Voice Agents**             |

<Note>
  **Inbound only:** xAI Voice Agents answer incoming calls. They don't place outbound calls. See [Outbound calls](#outbound-calls).
</Note>

***

## Prerequisites

| Requirement       | Description                                                                            |
| ----------------- | -------------------------------------------------------------------------------------- |
| **Plivo Account** | [Sign up](https://cx.plivo.com/signup) with SIP trunking enabled                       |
| **Phone Number**  | [Purchase a voice-enabled number](https://cx.plivo.com/phone-numbers)                  |
| **xAI Account**   | An account in the [xAI Console](https://console.x.ai/) with access to **Voice Agents** |

For the code samples, you also need:

* Your Plivo **Auth ID** and **Auth Token**, available on the [Plivo Console home page](https://cx.plivo.com/home). The Plivo API uses HTTP Basic authentication.
* An xAI **API key**, created on the **API Keys** page of the [xAI Console](https://console.x.ai/). The xAI API uses Bearer authentication.
* The [Plivo CLI](/docs/cli/install), logged in with [`plivo login`](/docs/cli/authenticate). The CLI uses the profile saved by `plivo login`, not the environment variables below.

Export your credentials as environment variables to use with the cURL, Python, and Node samples:

```shell theme={null}
export PLIVO_AUTH_ID="<your_auth_id>"
export PLIVO_AUTH_TOKEN="<your_auth_token>"
export XAI_API_KEY="<your_xai_api_key>"
```

***

## Inbound calls

Set up the agent in xAI, route your Plivo number to xAI, and then connect the number to the agent.

<Steps>
  <Step title="Create a voice agent in the xAI Console" titleSize="h3">
    Create the agent in the xAI Console. xAI doesn't provide APIs to create or manage voice agents.

    1. Sign in to the [xAI Console](https://console.x.ai/) and select **Voice Agents** in the left navigation.
    2. Select **Create agent**. A builder chat asks about your use case. Describe it, or select **Skip** to configure the agent yourself.
    3. Alternatively, select a template (such as **Customer Support** or **Appointment Scheduler**) or **Start from scratch** from the agents list. The agent is created as soon as you select one.
    4. To rename the agent, select the pencil icon next to its name, enter a **Name**, and select **Save**.

    Copy the agent ID from the page URL, for example `agent_a1B2c3D4e5F6g7H8`.
  </Step>

  <Step title="Configure and publish the agent" titleSize="h3">
    1. On the **Configuration** tab, enter the agent's **Instructions**.
    2. Turn on **Welcome message** and enter a greeting to have the agent speak first. When it's off, the agent waits for the caller to speak.
    3. Optional: review the settings that matter on a phone call:

    | Setting                        | Tab           | What it does                                                                                 |
    | ------------------------------ | ------------- | -------------------------------------------------------------------------------------------- |
    | **Caller can interrupt**       | Configuration | Lets caller speech interrupt the welcome message.                                            |
    | **Know caller's phone number** | Configuration | Lets the agent see and use the caller's phone number during the call.                        |
    | **Voice**                      | Speech        | Selects a built-in or custom voice.                                                          |
    | **Language**                   | Speech        | Improves recognition when callers speak a specific language. The default is **Auto-detect**. |
    | **Follow-up after silence**    | Speech        | Prompts callers when they go quiet.                                                          |

    4. Select **Publish**.

    <Warning>
      **Publish after every change:** Edits are saved as a draft, and the agent's status changes from **Live** to **Draft**. Calls use the published version until you select **Publish** again.
    </Warning>
  </Step>

  <Step title="Create an inbound trunk in Plivo" titleSize="h3">
    Create an inbound trunk that sends calls to xAI's SIP endpoint, `sip.voice.x.ai`, over TLS.

    <Tabs>
      <Tab title="Console">
        1. Sign in to the [Plivo Console](https://cx.plivo.com/).
        2. Navigate to **SIP Trunking** → [**Inbound Trunks**](https://cx.plivo.com/sip-trunking/inbound) and select **Create Trunk**.
        3. Enter a **Trunk Name**, for example `xAI-Inbound`.
        4. For **SIP Platform**, select **xAI (SpaceXAI)**. The **Primary URI** is filled in with the xAI SIP URI, `sip:sip.voice.x.ai;transport=tls`.
        5. Select **Create Trunk**.
      </Tab>

      <Tab title="API">
        First, create an [origination URI](/docs/sip-trunking/api/origination-uris) that points to xAI's SIP endpoint over TLS:

        <CodeGroup>
          ```shell CLI theme={null}
          plivo sip uris create --name xAI-Primary --uri "sip.voice.x.ai;transport=tls"
          ```

          ```shell cURL theme={null}
          curl "https://api.plivo.com/v1/Account/$PLIVO_AUTH_ID/Zentrunk/URI/" \
          -u "$PLIVO_AUTH_ID:$PLIVO_AUTH_TOKEN" \
          -H 'Content-Type: application/json' \
          -d '{
            "name": "xAI-Primary",
            "uri": "sip.voice.x.ai;transport=tls"
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          auth_id = os.environ["PLIVO_AUTH_ID"]
          auth_token = os.environ["PLIVO_AUTH_TOKEN"]

          response = requests.post(
              f"https://api.plivo.com/v1/Account/{auth_id}/Zentrunk/URI/",
              auth=(auth_id, auth_token),
              json={
                  "name": "xAI-Primary",
                  "uri": "sip.voice.x.ai;transport=tls",
              },
          )
          print(response.json())
          ```

          ```javascript Node theme={null}
          const authId = process.env.PLIVO_AUTH_ID;
          const authToken = process.env.PLIVO_AUTH_TOKEN;
          const authHeader = 'Basic ' + Buffer.from(`${authId}:${authToken}`).toString('base64');

          const response = await fetch(`https://api.plivo.com/v1/Account/${authId}/Zentrunk/URI/`, {
            method: 'POST',
            headers: {
              'Authorization': authHeader,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              name: 'xAI-Primary',
              uri: 'sip.voice.x.ai;transport=tls',
            }),
          });
          console.log(await response.json());
          ```
        </CodeGroup>

        Copy the `uri_uuid` from the response for the next request:

        ```json theme={null}
        {
          "api_id": "<api_id>",
          "message": "Origination URI created successfully",
          "uri_uuid": "<uri_uuid>"
        }
        ```

        Then create an [inbound trunk](/docs/sip-trunking/api/trunks) that uses the URI as its primary URI:

        <CodeGroup>
          ```shell CLI theme={null}
          plivo sip trunks create --name xAI-Inbound --direction inbound --uri <uri_uuid>
          ```

          ```shell cURL theme={null}
          curl "https://api.plivo.com/v1/Account/$PLIVO_AUTH_ID/Zentrunk/Trunk/" \
          -u "$PLIVO_AUTH_ID:$PLIVO_AUTH_TOKEN" \
          -H 'Content-Type: application/json' \
          -d '{
            "name": "xAI-Inbound",
            "trunk_direction": "inbound",
            "primary_uri_uuid": "<uri_uuid>"
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          auth_id = os.environ["PLIVO_AUTH_ID"]
          auth_token = os.environ["PLIVO_AUTH_TOKEN"]

          response = requests.post(
              f"https://api.plivo.com/v1/Account/{auth_id}/Zentrunk/Trunk/",
              auth=(auth_id, auth_token),
              json={
                  "name": "xAI-Inbound",
                  "trunk_direction": "inbound",
                  "primary_uri_uuid": "<uri_uuid>",
              },
          )
          print(response.json())
          ```

          ```javascript Node theme={null}
          const authId = process.env.PLIVO_AUTH_ID;
          const authToken = process.env.PLIVO_AUTH_TOKEN;
          const authHeader = 'Basic ' + Buffer.from(`${authId}:${authToken}`).toString('base64');

          const response = await fetch(`https://api.plivo.com/v1/Account/${authId}/Zentrunk/Trunk/`, {
            method: 'POST',
            headers: {
              'Authorization': authHeader,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              name: 'xAI-Inbound',
              trunk_direction: 'inbound',
              primary_uri_uuid: '<uri_uuid>',
            }),
          });
          console.log(await response.json());
          ```
        </CodeGroup>

        Copy the `trunk_id` from the response for the next step:

        ```json theme={null}
        {
          "api_id": "<api_id>",
          "message": "Trunk created successfully.",
          "trunk_id": "<trunk_id>"
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Connect your phone number" titleSize="h3">
    Route calls to your Plivo phone number through the inbound trunk.

    <Tabs>
      <Tab title="Console">
        1. Navigate to [**Phone Numbers**](https://cx.plivo.com/phone-numbers) and select your phone number.
        2. For **Application Type**, select **SIP Trunk**.
        3. For **SIP Inbound Trunk**, select the trunk you created in the previous step.
        4. Select **Save changes**.
      </Tab>

      <Tab title="API">
        Assign the inbound trunk to your phone number using the [update a number](/docs/numbers/account-phone-numbers#update-an-account-phone-number) endpoint. Set `app_id` to the **trunk ID** of your inbound trunk. Use your phone number in E.164 format without the leading `+`, for example `15105550100`:

        <CodeGroup>
          ```shell CLI theme={null}
          plivo numbers update 15105550100 --trunk-id <trunk_id>
          ```

          ```shell cURL theme={null}
          curl "https://api.plivo.com/v1/Account/$PLIVO_AUTH_ID/Number/15105550100/" \
          -u "$PLIVO_AUTH_ID:$PLIVO_AUTH_TOKEN" \
          -H 'Content-Type: application/json' \
          -d '{
            "app_id": "<trunk_id>"
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          auth_id = os.environ["PLIVO_AUTH_ID"]
          auth_token = os.environ["PLIVO_AUTH_TOKEN"]
          phone_number = "15105550100"

          response = requests.post(
              f"https://api.plivo.com/v1/Account/{auth_id}/Number/{phone_number}/",
              auth=(auth_id, auth_token),
              json={
                  "app_id": "<trunk_id>",
              },
          )
          print(response.json())
          ```

          ```javascript Node theme={null}
          const authId = process.env.PLIVO_AUTH_ID;
          const authToken = process.env.PLIVO_AUTH_TOKEN;
          const authHeader = 'Basic ' + Buffer.from(`${authId}:${authToken}`).toString('base64');
          const phoneNumber = '15105550100';

          const response = await fetch(`https://api.plivo.com/v1/Account/${authId}/Number/${phoneNumber}/`, {
            method: 'POST',
            headers: {
              'Authorization': authHeader,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              app_id: '<trunk_id>',
            }),
          });
          console.log(await response.json());
          ```
        </CodeGroup>

        A successful response returns HTTP `202`:

        ```json theme={null}
        {
          "api_id": "<api_id>",
          "message": "changed"
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Assign the number to your agent" titleSize="h3">
    Add your Plivo phone number to the agent, and allow all of Plivo's [signaling IP addresses](/docs/sip-trunking#signaling-/-media-ip-addresses). xAI accepts calls for the number only from these ranges, and Plivo can route a call through any region during a service disruption:

    ```text theme={null}
    13.52.9.0/25
    216.120.187.128/26
    18.214.109.128/25
    18.215.142.0/26
    204.89.148.128/26
    3.120.121.128/26
    18.228.70.64/26
    54.233.191.0/27
    13.238.202.192/26
    18.136.1.128/26
    204.89.149.128/27
    15.207.90.192/31
    204.89.151.128/27
    204.89.151.160/27
    ```

    To authenticate Plivo with a SIP username and password instead, see [Use SIP digest authentication](#use-sip-digest-authentication).

    <Tabs>
      <Tab title="Console">
        1. In the [xAI Console](https://console.x.ai/), open your agent and select the **Deployment** tab.
        2. Under **Phone numbers**, select **Add number**.
        3. Select **Direct SIP**. You're connecting your own Plivo number, so you don't need a phone number from xAI. If the dialog says xAI can't provision numbers in your region, you can continue.
        4. Enter a **Name** and your **Phone number** in E.164 format, for example `+15105550100`.
        5. Under **Allowed addresses**, enter each IP address range from the list above, and select **Add** after each one.
        6. Select **Add number**.

        <Tip>
          **Add the ranges faster:** The field accepts one range at a time. Press **Enter** after each range instead of selecting **Add**. To add all 14 ranges in a single request, use the **API** tab instead.
        </Tip>

        The number appears under **Phone numbers** with **Provisioned by** set to **Direct SIP**.
      </Tab>

      <Tab title="API">
        Register your number with xAI using [create a phone number](https://docs.x.ai/developers/rest-api-reference/inference/voice). Set `origin` to `byo_trunk`, `agent_id` to your agent ID, and `sip_auth.allowed_addresses` to Plivo's IP address ranges:

        <CodeGroup>
          ```shell cURL theme={null}
          curl "https://api.x.ai/v2/phone-numbers" \
          -H "Authorization: Bearer $XAI_API_KEY" \
          -H 'Content-Type: application/json' \
          -d '{
            "origin": "byo_trunk",
            "name": "Plivo inbound",
            "phone_number": "+15105550100",
            "agent_id": "<agent_id>",
            "sip_auth": {
              "allowed_addresses": [
                "13.52.9.0/25", "216.120.187.128/26",
                "18.214.109.128/25", "18.215.142.0/26", "204.89.148.128/26",
                "3.120.121.128/26",
                "18.228.70.64/26", "54.233.191.0/27",
                "13.238.202.192/26",
                "18.136.1.128/26", "204.89.149.128/27",
                "15.207.90.192/31", "204.89.151.128/27", "204.89.151.160/27"
              ]
            }
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          plivo_ip_ranges = [
              "13.52.9.0/25", "216.120.187.128/26",
              "18.214.109.128/25", "18.215.142.0/26", "204.89.148.128/26",
              "3.120.121.128/26",
              "18.228.70.64/26", "54.233.191.0/27",
              "13.238.202.192/26",
              "18.136.1.128/26", "204.89.149.128/27",
              "15.207.90.192/31", "204.89.151.128/27", "204.89.151.160/27",
          ]

          response = requests.post(
              "https://api.x.ai/v2/phone-numbers",
              headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
              json={
                  "origin": "byo_trunk",
                  "name": "Plivo inbound",
                  "phone_number": "+15105550100",
                  "agent_id": "<agent_id>",
                  "sip_auth": {"allowed_addresses": plivo_ip_ranges},
              },
          )
          print(response.json())
          ```

          ```javascript Node theme={null}
          const plivoIpRanges = [
            '13.52.9.0/25', '216.120.187.128/26',
            '18.214.109.128/25', '18.215.142.0/26', '204.89.148.128/26',
            '3.120.121.128/26',
            '18.228.70.64/26', '54.233.191.0/27',
            '13.238.202.192/26',
            '18.136.1.128/26', '204.89.149.128/27',
            '15.207.90.192/31', '204.89.151.128/27', '204.89.151.160/27',
          ];

          const response = await fetch('https://api.x.ai/v2/phone-numbers', {
            method: 'POST',
            headers: {
              'Authorization': `Bearer ${process.env.XAI_API_KEY}`,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              origin: 'byo_trunk',
              name: 'Plivo inbound',
              phone_number: '+15105550100',
              agent_id: '<agent_id>',
              sip_auth: { allowed_addresses: plivoIpRanges },
            }),
          });
          console.log(await response.json());
          ```
        </CodeGroup>

        A successful response returns HTTP `201` with the registered number. Copy the `phone_number_id` if you plan to [update the number later](#update-a-registered-number):

        ```json theme={null}
        {
          "phone_number": {
            "phone_number_id": "<phone_number_id>",
            "team_id": "<team_id>",
            "phone_number": "+15105550100",
            "name": "Plivo inbound",
            "agent_id": "<agent_id>",
            "origin": "byo_trunk",
            "sip_host": "<sip_host>",
            "inbound_trunk_id": "<inbound_trunk_id>",
            "sip_auth": {
              "allowed_addresses": [
                "13.52.9.0/25",
                "216.120.187.128/26",
                "18.214.109.128/25",
                "18.215.142.0/26",
                "204.89.148.128/26",
                "3.120.121.128/26",
                "18.228.70.64/26",
                "54.233.191.0/27",
                "13.238.202.192/26",
                "18.136.1.128/26",
                "204.89.149.128/27",
                "15.207.90.192/31",
                "204.89.151.128/27",
                "204.89.151.160/27"
              ]
            },
            "created_at": "2026-09-25T22:33:26.376958+00:00",
            "updated_at": "2026-09-25T22:33:26.376958+00:00"
          }
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Test the integration" titleSize="h3">
    1. Call your Plivo phone number. The agent answers with its welcome message.
    2. In the xAI Console, open your agent and select the **Conversations** tab. Select a call to see its transcript, per-turn audio, and raw events. xAI keeps conversations for 30 days.
  </Step>
</Steps>

***

## Outbound calls

xAI Voice Agents don't support outbound calling. You don't need a Plivo outbound trunk for this integration.

***

## Use SIP digest authentication

To authenticate Plivo with a SIP username and password instead of IP address ranges, add the same credentials in Plivo and xAI:

* **Username:** 5 to 20 characters, alphanumeric only.
* **Password:** 5 to 20 characters, using only alphanumeric characters and the special characters `~!@#$%^&*()_+`, with at least one special character.

**In Plivo**, turn on authentication for the trunk's primary URI:

<Tabs>
  <Tab title="Console">
    1. Navigate to **SIP Trunking** → [**Inbound Trunks**](https://cx.plivo.com/sip-trunking/inbound) and open your xAI trunk.
    2. Open the **Primary URI** list and select the pencil icon next to the xAI URI.
    3. Turn on **Authentication needed**, then enter the **Username** and **Password**.
    4. Select **Update URI**.
  </Tab>

  <Tab title="API">
    Update the [origination URI](/docs/sip-trunking/api/origination-uris) with `authentication_needed`, `username`, and `password`:

    <CodeGroup>
      ```shell CLI theme={null}
      printf '%s' '<password>' | plivo sip uris update <uri_uuid> --authentication-needed=true --username <username> --password-stdin
      ```

      ```shell cURL theme={null}
      curl "https://api.plivo.com/v1/Account/$PLIVO_AUTH_ID/Zentrunk/URI/<uri_uuid>/" \
      -u "$PLIVO_AUTH_ID:$PLIVO_AUTH_TOKEN" \
      -H 'Content-Type: application/json' \
      -d '{
        "authentication_needed": true,
        "username": "<username>",
        "password": "<password>"
      }'
      ```

      ```python Python theme={null}
      import os
      import requests

      auth_id = os.environ["PLIVO_AUTH_ID"]
      auth_token = os.environ["PLIVO_AUTH_TOKEN"]

      response = requests.post(
          f"https://api.plivo.com/v1/Account/{auth_id}/Zentrunk/URI/<uri_uuid>/",
          auth=(auth_id, auth_token),
          json={
              "authentication_needed": True,
              "username": "<username>",
              "password": "<password>",
          },
      )
      print(response.json())
      ```

      ```javascript Node theme={null}
      const authId = process.env.PLIVO_AUTH_ID;
      const authToken = process.env.PLIVO_AUTH_TOKEN;
      const authHeader = 'Basic ' + Buffer.from(`${authId}:${authToken}`).toString('base64');

      const response = await fetch(`https://api.plivo.com/v1/Account/${authId}/Zentrunk/URI/<uri_uuid>/`, {
        method: 'POST',
        headers: {
          'Authorization': authHeader,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          authentication_needed: true,
          username: '<username>',
          password: '<password>',
        }),
      });
      console.log(await response.json());
      ```
    </CodeGroup>
  </Tab>
</Tabs>

**In xAI**, add the same credentials to your phone number:

<Tabs>
  <Tab title="Console">
    When you add the number in [Assign the number to your agent](#assign-the-number-to-your-agent), expand **Authentication** and enter the **Username** and **Password**. You can leave **Allowed addresses** empty.

    You can't change the authentication of a number you already added. To switch an existing number to SIP digest authentication, select **⋯** → **Edit** → **Remove number** on the number under **Phone numbers**, and then add it again.
  </Tab>

  <Tab title="API">
    Register your number with `sip_auth.auth_username` and `sip_auth.auth_password` instead of `allowed_addresses`:

    <CodeGroup>
      ```shell cURL theme={null}
      curl "https://api.x.ai/v2/phone-numbers" \
      -H "Authorization: Bearer $XAI_API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{
        "origin": "byo_trunk",
        "name": "Plivo inbound",
        "phone_number": "+15105550100",
        "agent_id": "<agent_id>",
        "sip_auth": {
          "auth_username": "<username>",
          "auth_password": "<password>"
        }
      }'
      ```

      ```python Python theme={null}
      import os
      import requests

      response = requests.post(
          "https://api.x.ai/v2/phone-numbers",
          headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
          json={
              "origin": "byo_trunk",
              "name": "Plivo inbound",
              "phone_number": "+15105550100",
              "agent_id": "<agent_id>",
              "sip_auth": {
                  "auth_username": "<username>",
                  "auth_password": "<password>",
              },
          },
      )
      print(response.json())
      ```

      ```javascript Node theme={null}
      const response = await fetch('https://api.x.ai/v2/phone-numbers', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.XAI_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          origin: 'byo_trunk',
          name: 'Plivo inbound',
          phone_number: '+15105550100',
          agent_id: '<agent_id>',
          sip_auth: {
            auth_username: '<username>',
            auth_password: '<password>',
          },
        }),
      });
      console.log(await response.json());
      ```
    </CodeGroup>

    A successful response returns HTTP `201`. The `sip_auth` object contains only the username:

    ```json theme={null}
    {
      "phone_number": {
        "phone_number_id": "<phone_number_id>",
        "team_id": "<team_id>",
        "phone_number": "+15105550100",
        "name": "Plivo inbound",
        "agent_id": "<agent_id>",
        "origin": "byo_trunk",
        "sip_host": "<sip_host>",
        "inbound_trunk_id": "<inbound_trunk_id>",
        "sip_auth": {
          "auth_username": "<username>"
        },
        "created_at": "2026-09-25T22:33:26.376958+00:00",
        "updated_at": "2026-09-25T22:33:26.376958+00:00"
      }
    }
    ```

    xAI never returns the password, and you can't change the authentication of an existing number. To change it, [delete the number](#update-a-registered-number) and register it again.
  </Tab>
</Tabs>

***

## Make changes after setup

### Update the agent

To change the agent's instructions, voice, or tools, edit the agent in the xAI Console and select **Publish**. Nothing changes in Plivo.

### Update a registered number

You can rename a registered number, and with the API, route it to a different agent. Its allowed IP address ranges and SIP credentials can't be changed in place: remove the number and add it again with the new values.

<Tabs>
  <Tab title="Console">
    1. Open the agent's **Deployment** tab and select **⋯** → **Edit** on the number.
    2. Change the **Name** and select **Save**.
    3. To change the allowed IP address ranges or SIP credentials, select **Remove number**, and then add the number again.
  </Tab>

  <Tab title="API">
    Send these requests to `https://api.x.ai`. For `PATCH`, put the fields to change in `phone_number` and list them in `field_mask.paths`. Only `name` and `agent_id` can be changed this way:

    | Task                                                    | Request                                                                                                                                                    |
    | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | List your numbers and their `phone_number_id`           | `GET /v2/phone-numbers`                                                                                                                                    |
    | Route the number to a different agent                   | `PATCH /v2/phone-numbers/<phone_number_id>` with `{"phone_number": {"agent_id": "<agent_id>"}, "field_mask": {"paths": ["agent_id"]}}`                     |
    | Rename the number                                       | `PATCH /v2/phone-numbers/<phone_number_id>` with `{"phone_number": {"name": "<name>"}, "field_mask": {"paths": ["name"]}}`                                 |
    | Change the allowed IP address ranges or SIP credentials | `DELETE /v2/phone-numbers/<phone_number_id>`, and then register the number again as in [Assign the number to your agent](#assign-the-number-to-your-agent) |
  </Tab>
</Tabs>

***

## Troubleshooting

SIP configuration errors typically surface only when a call is placed. If a call fails, check the following common issues:

| Issue                                                          | Solution                                                                                                                                                                                                                            |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Call fails and doesn't appear in the agent's **Conversations** | Verify the trunk's primary URI is `sip.voice.x.ai;transport=tls`, and that your phone number's **Application Type** is **SIP Trunk** with your xAI trunk selected. In xAI, verify the number is in E.164 format with a leading `+`. |
| Call is rejected by xAI                                        | Verify **Allowed addresses** includes all of Plivo's IP address ranges. If you use SIP digest authentication, verify the username and password match exactly in Plivo and xAI.                                                      |
| Agent uses old instructions                                    | Select **Publish** in the xAI Console. Calls use the published version, not the draft.                                                                                                                                              |
| Agent stays silent when the call connects                      | **Welcome message** is off, so the agent waits for the caller to speak first. Turn it on to have the agent greet callers.                                                                                                           |

**Debug logs:**

* Call doesn't reach the agent: first check the [Plivo logs](https://cx.plivo.com/logs/sip-trunking), then the agent's **Conversations** tab in the xAI Console.
* Call reaches the agent but behaves unexpectedly: check the call's transcript and **Raw events** in the agent's **Conversations** tab.

For error codes, see [Plivo hangup codes](/docs/voice-agents/sip-trunking/troubleshooting/hangup-codes).

***

## Related

<CardGroup cols={2}>
  <Card title="SIP Trunking API overview" href="/docs/sip-trunking/api/overview">
    Plivo SIP Trunking API reference.
  </Card>

  <Card title="SIP Trunking overview" href="/docs/sip-trunking">
    Plivo SIP trunking documentation.
  </Card>

  <Card title="xAI SIP Phone Calls" href="https://docs.x.ai/developers/model-capabilities/audio/speech-to-speech/sip">
    xAI's SIP documentation.
  </Card>

  <Card title="xAI Voice API reference" href="https://docs.x.ai/developers/rest-api-reference/inference/voice">
    xAI phone number and realtime API reference.
  </Card>
</CardGroup>
