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

# SMS Messaging

> Send SMS messages from your Guava numbers and wait for replies

The [`guava.Client`](/sdk-reference/client) can send SMS messages from your Guava numbers and wait for inbound replies. This is useful for sending confirmations and reminders, or for collecting a response between calls.

<Note>
  SMS messaging is available in the **Python and TypeScript SDKs**. For other languages, call the equivalent [Messages REST API](/api-reference/messages-api) directly.
</Note>

<CodeGroup>
  ```python Python theme={null}
  import guava
  import os

  client = guava.Client(api_key=os.environ["GUAVA_API_KEY"])

  agent_number = os.environ["GUAVA_AGENT_NUMBER"]   # one of your Guava numbers
  customer = "+15551234567"

  # Send an SMS from your Guava number to the customer.
  client.send_sms(
      from_number=agent_number,
      to_number=customer,
      message="Hi! Reply YES to confirm your appointment, or STOP to opt out.",
  )

  # Block until the customer replies, giving up after 5 minutes.
  reply = client.next_sms(from_number=customer, to_number=agent_number, timeout=300)

  if reply is None:
      print("No reply within 5 minutes.")
  else:
      print("Customer replied:", reply["content"])
  ```

  ```typescript TypeScript theme={null}
  import * as guava from "@guava-ai/guava-sdk";

  const client = new guava.Client({ apiKey: process.env.GUAVA_API_KEY });

  const agentNumber = process.env.GUAVA_AGENT_NUMBER;  // one of your Guava numbers
  const customer = "+15551234567";

  // Send an SMS from your Guava number to the customer.
  await client.sendSms(
    agentNumber,
    customer,
    "Hi! Reply YES to confirm your appointment, or STOP to opt out.",
  );

  // Block until the customer replies, giving up after 5 minutes.
  const reply = await client.nextSms(customer, agentNumber, { timeoutMs: 300_000 });

  if (reply === null) {
    console.log("No reply within 5 minutes.");
  } else {
    console.log("Customer replied:", reply.content);
  }
  ```
</CodeGroup>

## send\_sms / sendSms

Send a single SMS message. The `from_number` must be one of your Guava numbers with SMS configured, and the message is delivered to `to_number`.

<CodeGroup>
  ```python Python theme={null}
  client.send_sms(
      from_number: str,
      to_number: str,
      message: str,
  ) -> None
  ```

  ```typescript TypeScript theme={null}
  await client.sendSms(
    fromNumber: string,
    toNumber: string,
    message: string,
  ): Promise<void>
  ```
</CodeGroup>

| Parameter | Type | Description |
| - | - | - |
| `from_number` | `str` | One of your Guava numbers, in E.164 format (e.g. `"+15551230001"`). Must have SMS enabled. |
| `to_number` | `str` | The recipient's number, in E.164 format. |
| `message` | `str` | The message body to send. |

Returns nothing (Python `None`; TypeScript resolves `void`). Raises (Python) / rejects (TypeScript) if the `from_number` isn't owned by your organization or doesn't have SMS configured.

<Note>
  Sending SMS requires your organization to complete SMS brand and campaign registration. See [Outbound & SMS Compliance](/guides/outbound-and-sms-permissions).
</Note>

## next\_sms / nextSms

Wait for the next inbound SMS sent **to** one of your Guava numbers **from** a given number, and return it. `next_sms` polls your inbox and only returns messages received after the call begins, so a reply to an earlier message won't be returned twice.

<Note>
  Note the direction: `from_number` is the external number you're waiting to hear from (the customer), and `to_number` is your Guava number that receives the reply — the opposite of `send_sms`.
</Note>

<CodeGroup>
  ```python Python theme={null}
  client.next_sms(
      from_number: str,
      to_number: str,
      *,
      timeout: float = 60.0,
      poll_interval: float = 2.0,
  ) -> dict | None
  ```

  ```typescript TypeScript theme={null}
  await client.nextSms(
    fromNumber: string,
    toNumber: string,
    options?: { timeoutMs?: number; pollIntervalMs?: number },
  ): Promise<SmsMessage | null>
  ```
</CodeGroup>

| Parameter | Type | Default | Description |
| - | - | - | - |
| `from_number` | `str` | | The external number you're waiting to hear from, in E.164 format. |
| `to_number` | `str` | | Your Guava number that will receive the reply, in E.164 format. |
| `timeout` | `float` | `60.0` | Maximum number of seconds to wait before giving up. In TypeScript, pass `timeoutMs` (milliseconds) in the options object; defaults to 60000. |
| `poll_interval` | `float` | `2.0` | Seconds to wait between inbox checks. In TypeScript, pass `pollIntervalMs` (milliseconds) in the options object; defaults to 2000. |

Returns the message (Python `dict` / TypeScript `SmsMessage`), or `None` / `null` if the timeout elapses with no new message. A message has the following fields:

| Field | Type | Description |
| - | - | - |
| `id` | `str` | Unique ID of the message. |
| `from_number` | `str` | The number that sent the message. |
| `to_number` | `str` | Your Guava number that received the message. |
| `content` | `str` | The message body. |
| `received_at` | `str` | When the message was received, in ISO 8601 format. |
| `modality` | `str` | The channel the message arrived on. Currently always `"sms"`. |
| `direction` | `str` | Always `"inbound"` for received messages. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.