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

# Node.js SDK SMS service

> Use the AvraAPI Node.js SDK to send SMS or read the configured SMS balance.

Use `avraapi.sms()` for the four released SMS operations. All return Promises
for `ApiResponse`. Sending is a real external action: success means the
configured QuickSend integration accepted the request, not that a handset
received it. Do not automatically retry an uncertain send.

<Note>
  Every SMS operation supports the shared one-request privacy control:
  `avraapi.sms().withPrivacyMode().getBalance()`. It sends
  `X-Privacy-Mode: 1` for that request only, then clears automatically.
</Note>

<Warning>
  Send messages only to recipients you own or are permitted to contact. Keep
  all send workflows in your backend, retain `requestId`, and decide whether to
  retry only after checking if the provider accepted the original request.
</Warning>

## Send one SMS

`sendSingle({ to, message }): Promise<ApiResponse<SmsSendData>>` sends one
message to a QuickSend-compatible Sri Lankan local `07XXXXXXXX` or E.164
`+947XXXXXXXX` number. A Managed SMS integration supports this method.

**SDK function**

```ts title="Copy the SDK call" theme={null}
const response = await avraapi.sms().sendSingle({
  to: 'RECIPIENT_NUMBER',
  message: 'Text message',
});
```

| Field | Use |
| - | - |
| `to` | One compatible recipient number. |
| `message` | Text message for that recipient. |

```ts title="Send one SMS and capture acceptance" theme={null}
// AvraAPI SDK call.
const response = await avraapi.sms().sendSingle({
  to: 'RECIPIENT_NUMBER',
  message: 'Text message',
});

// Your application code.
const messageUnits = response.data.message_count;
const providerId = response.data.provider_response.id;
const requestId = response.requestId;
```

### Response

```json theme={null}
{
  "success": true,
  "request_id": "1af26040-c878-472f-88bd-6c5158905637",
  "data": {
    "send_method": "single",
    "message_count": 1,
    "credits_charged": 2000,
    "provider_response": {"status": "success", "id": "4726abaf7ab34f31378"}
  }
}
```

## Send one message to a bulk list

`sendBulkSame({ recipients, message, checkCost? })` sends the same text to
1–10,000 recipients. It requires a Manual (BYOK) QuickSend integration. Set
`checkCost: true` to request a campaign estimate instead of dispatching it.

**SDK function**

```ts title="Copy the SDK call" theme={null}
const response = await avraapi.sms().sendBulkSame({
  recipients: ['FIRST_RECIPIENT_NUMBER', 'SECOND_RECIPIENT_NUMBER'],
  message: 'Text message',
  checkCost: true,
});
```

| Field | Use |
| - | - |
| `recipients` | Array of one to 10,000 compatible numbers. |
| `message` | Shared text message. |
| `checkCost` | Optional; `true` estimates cost without dispatching. |

```ts title="Check the cost before a bulk campaign" theme={null}
// AvraAPI SDK call. This requests an estimate; it does not dispatch the campaign.
const response = await avraapi.sms().sendBulkSame({
  recipients: ['FIRST_RECIPIENT_NUMBER', 'SECOND_RECIPIENT_NUMBER'],
  message: 'Text message',
  checkCost: true,
});

// Your application code.
const campaign = response.data.provider_response.campaign_data;
const messageUnits = response.data.message_count;
```

### Response

```json theme={null}
{
  "success": true,
  "request_id": "d5ca2bbb-9cab-42ef-932a-62ef61470447",
  "data": {
    "send_method": "bulk_same",
    "message_count": 2,
    "credits_charged": 0,
    "provider_response": {
      "status": "success",
      "campaign_data": {
        "campaign_method": "Same Message To Bulk",
        "campaign_total_cost": "1.12 LKR (0.56×2)",
        "campaign_total_numbers": "2 Numbers"
      }
    }
  }
}
```

With `checkCost: false`, the same method submits the campaign and
`provider_response` contains the provider acceptance result. Manual (BYOK)
sends return `credits_charged: 0`; the connected provider can charge its own
account.

## Send different messages to a bulk list

`sendBulkDifferent({ msgList })` sends a different message to each recipient
through a Manual (BYOK) QuickSend integration. Supply 1–20 entries; each has
exactly `to` and `msg`.

**SDK function**

```ts title="Copy the SDK call" theme={null}
const response = await avraapi.sms().sendBulkDifferent({
  msgList: [{ to: 'FIRST_RECIPIENT_NUMBER', msg: 'First text message' }],
});
```

| Field | Use |
| - | - |
| `msgList` | Array of one to 20 `{ to, msg }` entries. |

```ts title="Send recipient-specific SMS messages" theme={null}
// AvraAPI SDK call. This is a real send operation.
const response = await avraapi.sms().sendBulkDifferent({
  msgList: [
    { to: 'FIRST_RECIPIENT_NUMBER', msg: 'First text message' },
    { to: 'SECOND_RECIPIENT_NUMBER', msg: 'Second text message' },
  ],
});

// Your application code.
const acceptedUnits = response.data.message_count;
const providerId = response.data.provider_response.id;
```

### Response

```json theme={null}
{
  "success": true,
  "request_id": "5bf45f1d-e0ee-4293-8a47-f033d1fb0c4a",
  "data": {
    "send_method": "bulk_different",
    "message_count": 2,
    "credits_charged": 0,
    "provider_response": {"status": "success", "id": "4726abafafabbb0a378"}
  }
}
```

`checkCost` is not an input of `sendBulkDifferent()`. A cost estimate is
available only through `sendBulkSame({ checkCost: true, ... })`.

## Check the configured SMS balance

`getBalance(): Promise<ApiResponse<SmsBalanceData>>` reads the active SMS
integration balance and does not deduct AvraAPI credits.

**SDK function**

```ts title="Copy the SDK call" theme={null}
const response = await avraapi.sms().getBalance();
```

```ts title="Read the SMS balance" theme={null}
// AvraAPI SDK call.
const response = await avraapi.sms().getBalance();

// Your application code.
const source = response.data.source;
const balance = response.data.balance_formatted;
const providerBalance = response.data.provider_response?.balance;
```

### Response — Manual (BYOK)

```json theme={null}
{
  "success": true,
  "request_id": "7a5b17fa-0716-45e1-b109-378322b8769f",
  "data": {
    "source": "quicksend_direct",
    "balance_formatted": "473.52",
    "provider_response": {"balance": "473.52"}
  }
}
```

### Response — Managed

```json theme={null}
{
  "success": true,
  "request_id": "3251caf2-3d8a-4232-a1fb-b4cfc4846888",
  "data": {"source": "apix_wallet", "balance_formatted": "285,417,005 credits"}
}
```

For a Managed integration, `balance_formatted` reports AvraAPI wallet credits:
**1 USD equals 1,000,000 API credits**. For a Manual integration it reports the
connected QuickSend balance.

## SMS units and errors

`message_count` is SMS units, not API request count. Use up to **153 GSM-7**
characters or **67 Unicode (UCS-2)** characters per unit. Each recipient
message is limited to three units. The [SMS REST API Reference](/api-reference/sms/send)
contains the full method restrictions and error contract. For failures, use the
typed error pattern in [Node.js Overview and setup](/sdk/nodejs/overview-and-setup#handle-errors-safely).


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