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

# Send SMS

> Learn how to configure the "Send SMS" action within a Pearl, allowing your AI agent to send SMS messages during a conversation.

export const SMS_COUNTRIES = [{
  code: 1,
  iso: "US",
  name: "United States",
  rate: 1
}, {
  code: 7,
  iso: "RU",
  name: "Russia",
  rate: 76
}, {
  code: 20,
  iso: "EG",
  name: "Egypt",
  rate: 40
}, {
  code: 27,
  iso: "ZA",
  name: "South Africa",
  rate: 14
}, {
  code: 30,
  iso: "GR",
  name: "Greece",
  rate: 7
}, {
  code: 31,
  iso: "NL",
  name: "Netherlands",
  rate: 12
}, {
  code: 32,
  iso: "BE",
  name: "Belgium",
  rate: 12
}, {
  code: 33,
  iso: "FR",
  name: "France",
  rate: 8
}, {
  code: 34,
  iso: "ES",
  name: "Spain",
  rate: 9
}, {
  code: 36,
  iso: "HU",
  name: "Hungary",
  rate: 10
}, {
  code: 39,
  iso: "IT",
  name: "Italy",
  rate: 10
}, {
  code: 40,
  iso: "RO",
  name: "Romania",
  rate: 8
}, {
  code: 41,
  iso: "CH",
  name: "Switzerland",
  rate: 8
}, {
  code: 43,
  iso: "AT",
  name: "Austria",
  rate: 10
}, {
  code: 44,
  iso: "GB",
  name: "United Kingdom",
  rate: 6
}, {
  code: 45,
  iso: "DK",
  name: "Denmark",
  rate: 6
}, {
  code: 46,
  iso: "SE",
  name: "Sweden",
  rate: 12
}, {
  code: 47,
  iso: "NO",
  name: "Norway",
  rate: 7
}, {
  code: 48,
  iso: "PL",
  name: "Poland",
  rate: 5
}, {
  code: 49,
  iso: "DE",
  name: "Germany",
  rate: 12
}, {
  code: 51,
  iso: "PE",
  name: "Peru",
  rate: 25
}, {
  code: 52,
  iso: "MX",
  name: "Mexico",
  rate: 19
}, {
  code: 54,
  iso: "AR",
  name: "Argentina",
  rate: 11
}, {
  code: 55,
  iso: "BR",
  name: "Brazil",
  rate: 7
}, {
  code: 56,
  iso: "CL",
  name: "Chile",
  rate: 8
}, {
  code: 57,
  iso: "CO",
  name: "Colombia",
  rate: 6
}, {
  code: 58,
  iso: "VE",
  name: "Venezuela",
  rate: 23
}, {
  code: 60,
  iso: "MY",
  name: "Malaysia",
  rate: 33
}, {
  code: 61,
  iso: "AU",
  name: "Australia",
  rate: 6
}, {
  code: 62,
  iso: "ID",
  name: "Indonesia",
  rate: 45
}, {
  code: 63,
  iso: "PH",
  name: "Philippines",
  rate: 25
}, {
  code: 64,
  iso: "NZ",
  name: "New Zealand",
  rate: 12
}, {
  code: 65,
  iso: "SG",
  name: "Singapore",
  rate: 7
}, {
  code: 66,
  iso: "TH",
  name: "Thailand",
  rate: 4
}, {
  code: 81,
  iso: "JP",
  name: "Japan",
  rate: 9
}, {
  code: 82,
  iso: "KR",
  name: "South Korea",
  rate: 6
}, {
  code: 84,
  iso: "VN",
  name: "Vietnam",
  rate: 29
}, {
  code: 86,
  iso: "CN",
  name: "China",
  rate: 11
}, {
  code: 90,
  iso: "TR",
  name: "Turkey",
  rate: 4
}, {
  code: 91,
  iso: "IN",
  name: "India",
  rate: 9
}, {
  code: 92,
  iso: "PK",
  name: "Pakistan",
  rate: 48
}, {
  code: 93,
  iso: "AF",
  name: "Afghanistan",
  rate: 45
}, {
  code: 94,
  iso: "LK",
  name: "Sri Lanka",
  rate: 42
}, {
  code: 95,
  iso: "MM",
  name: "Myanmar",
  rate: 42
}, {
  code: 211,
  iso: "SS",
  name: "South Sudan",
  rate: 24
}, {
  code: 212,
  iso: "MA",
  name: "Morocco",
  rate: 23
}, {
  code: 213,
  iso: "DZ",
  name: "Algeria",
  rate: 28
}, {
  code: 216,
  iso: "TN",
  name: "Tunisia",
  rate: 54
}, {
  code: 218,
  iso: "LY",
  name: "Libya",
  rate: 45
}, {
  code: 220,
  iso: "GM",
  name: "Gambia",
  rate: 27
}, {
  code: 221,
  iso: "SN",
  name: "Senegal",
  rate: 56
}, {
  code: 222,
  iso: "MR",
  name: "Mauritania",
  rate: 37
}, {
  code: 223,
  iso: "ML",
  name: "Mali",
  rate: 35
}, {
  code: 224,
  iso: "GN",
  name: "Guinea",
  rate: 28
}, {
  code: 225,
  iso: "CI",
  name: "Cote d'Ivoire",
  rate: 44
}, {
  code: 226,
  iso: "BF",
  name: "Burkina Faso",
  rate: 23
}, {
  code: 227,
  iso: "NE",
  name: "Niger",
  rate: 37
}, {
  code: 228,
  iso: "TG",
  name: "Togo",
  rate: 45
}, {
  code: 229,
  iso: "BJ",
  name: "Benin",
  rate: 30
}, {
  code: 230,
  iso: "MU",
  name: "Mauritius",
  rate: 27
}, {
  code: 231,
  iso: "LR",
  name: "Liberia",
  rate: 25
}, {
  code: 232,
  iso: "SL",
  name: "Sierra Leone",
  rate: 79
}, {
  code: 233,
  iso: "GH",
  name: "Ghana",
  rate: 38
}, {
  code: 234,
  iso: "NG",
  name: "Nigeria",
  rate: 39
}, {
  code: 235,
  iso: "TD",
  name: "Chad",
  rate: 35
}, {
  code: 236,
  iso: "CF",
  name: "Central African Republic",
  rate: 46
}, {
  code: 237,
  iso: "CM",
  name: "Cameroon",
  rate: 32
}, {
  code: 238,
  iso: "CV",
  name: "Cape Verde",
  rate: 23
}, {
  code: 239,
  iso: "ST",
  name: "Sao Tome and Principe",
  rate: 14
}, {
  code: 240,
  iso: "GQ",
  name: "Equatorial Guinea",
  rate: 28
}, {
  code: 241,
  iso: "GA",
  name: "Gabon",
  rate: 32
}, {
  code: 242,
  iso: "CG",
  name: "Republic of the Congo",
  rate: 34
}, {
  code: 243,
  iso: "CD",
  name: "DR Congo",
  rate: 26
}, {
  code: 244,
  iso: "AO",
  name: "Angola",
  rate: 31
}, {
  code: 245,
  iso: "GW",
  name: "Guinea-Bissau",
  rate: 48
}, {
  code: 248,
  iso: "SC",
  name: "Seychelles",
  rate: 31
}, {
  code: 249,
  iso: "SD",
  name: "Sudan",
  rate: 48
}, {
  code: 250,
  iso: "RW",
  name: "Rwanda",
  rate: 33
}, {
  code: 251,
  iso: "ET",
  name: "Ethiopia",
  rate: 35
}, {
  code: 252,
  iso: "SO",
  name: "Somalia",
  rate: 38
}, {
  code: 253,
  iso: "DJ",
  name: "Djibouti",
  rate: 17
}, {
  code: 254,
  iso: "KE",
  name: "Kenya",
  rate: 24
}, {
  code: 255,
  iso: "TZ",
  name: "Tanzania",
  rate: 44
}, {
  code: 256,
  iso: "UG",
  name: "Uganda",
  rate: 33
}, {
  code: 257,
  iso: "BI",
  name: "Burundi",
  rate: 47
}, {
  code: 258,
  iso: "MZ",
  name: "Mozambique",
  rate: 42
}, {
  code: 260,
  iso: "ZM",
  name: "Zambia",
  rate: 40
}, {
  code: 261,
  iso: "MG",
  name: "Madagascar",
  rate: 53
}, {
  code: 262,
  iso: "RE",
  name: "Reunion",
  rate: 20
}, {
  code: 263,
  iso: "ZW",
  name: "Zimbabwe",
  rate: 25
}, {
  code: 264,
  iso: "NA",
  name: "Namibia",
  rate: 11
}, {
  code: 265,
  iso: "MW",
  name: "Malawi",
  rate: 34
}, {
  code: 266,
  iso: "LS",
  name: "Lesotho",
  rate: 42
}, {
  code: 267,
  iso: "BW",
  name: "Botswana",
  rate: 16
}, {
  code: 268,
  iso: "SZ",
  name: "Eswatini",
  rate: 27
}, {
  code: 269,
  iso: "KM",
  name: "Comoros",
  rate: 42
}, {
  code: 291,
  iso: "ER",
  name: "Eritrea",
  rate: 13
}, {
  code: 297,
  iso: "AW",
  name: "Aruba",
  rate: 28
}, {
  code: 298,
  iso: "FO",
  name: "Faroe Islands",
  rate: 8
}, {
  code: 299,
  iso: "GL",
  name: "Greenland",
  rate: 5
}, {
  code: 350,
  iso: "GI",
  name: "Gibraltar",
  rate: 11
}, {
  code: 351,
  iso: "PT",
  name: "Portugal",
  rate: 6
}, {
  code: 352,
  iso: "LU",
  name: "Luxembourg",
  rate: 9
}, {
  code: 353,
  iso: "IE",
  name: "Ireland",
  rate: 8
}, {
  code: 354,
  iso: "IS",
  name: "Iceland",
  rate: 8
}, {
  code: 355,
  iso: "AL",
  name: "Albania",
  rate: 12
}, {
  code: 356,
  iso: "MT",
  name: "Malta",
  rate: 7
}, {
  code: 357,
  iso: "CY",
  name: "Cyprus",
  rate: 9
}, {
  code: 358,
  iso: "FI",
  name: "Finland",
  rate: 9
}, {
  code: 359,
  iso: "BG",
  name: "Bulgaria",
  rate: 15
}, {
  code: 370,
  iso: "LT",
  name: "Lithuania",
  rate: 9
}, {
  code: 371,
  iso: "LV",
  name: "Latvia",
  rate: 9
}, {
  code: 372,
  iso: "EE",
  name: "Estonia",
  rate: 10
}, {
  code: 373,
  iso: "MD",
  name: "Moldova",
  rate: 15
}, {
  code: 374,
  iso: "AM",
  name: "Armenia",
  rate: 30
}, {
  code: 375,
  iso: "BY",
  name: "Belarus",
  rate: 26
}, {
  code: 376,
  iso: "AD",
  name: "Andorra",
  rate: 15
}, {
  code: 377,
  iso: "MC",
  name: "Monaco",
  rate: 19
}, {
  code: 378,
  iso: "SM",
  name: "San Marino",
  rate: 13
}, {
  code: 380,
  iso: "UA",
  name: "Ukraine",
  rate: 23
}, {
  code: 381,
  iso: "RS",
  name: "Serbia",
  rate: 41
}, {
  code: 382,
  iso: "ME",
  name: "Montenegro",
  rate: 18
}, {
  code: 385,
  iso: "HR",
  name: "Croatia",
  rate: 14
}, {
  code: 386,
  iso: "SI",
  name: "Slovenia",
  rate: 21
}, {
  code: 387,
  iso: "BA",
  name: "Bosnia and Herzegovina",
  rate: 52
}, {
  code: 389,
  iso: "MK",
  name: "North Macedonia",
  rate: 21
}, {
  code: 420,
  iso: "CZ",
  name: "Czech Republic",
  rate: 8
}, {
  code: 421,
  iso: "SK",
  name: "Slovakia",
  rate: 9
}, {
  code: 423,
  iso: "LI",
  name: "Liechtenstein",
  rate: 4
}, {
  code: 500,
  iso: "FK",
  name: "Falkland Islands",
  rate: 17
}, {
  code: 501,
  iso: "BZ",
  name: "Belize",
  rate: 30
}, {
  code: 502,
  iso: "GT",
  name: "Guatemala",
  rate: 25
}, {
  code: 503,
  iso: "SV",
  name: "El Salvador",
  rate: 30
}, {
  code: 504,
  iso: "HN",
  name: "Honduras",
  rate: 33
}, {
  code: 505,
  iso: "NI",
  name: "Nicaragua",
  rate: 16
}, {
  code: 506,
  iso: "CR",
  name: "Costa Rica",
  rate: 9
}, {
  code: 507,
  iso: "PA",
  name: "Panama",
  rate: 19
}, {
  code: 508,
  iso: "PM",
  name: "Saint Pierre and Miquelon",
  rate: 16
}, {
  code: 509,
  iso: "HT",
  name: "Haiti",
  rate: 30
}, {
  code: 590,
  iso: "GP",
  name: "Guadeloupe",
  rate: 23
}, {
  code: 591,
  iso: "BO",
  name: "Bolivia",
  rate: 23
}, {
  code: 592,
  iso: "GY",
  name: "Guyana",
  rate: 34
}, {
  code: 593,
  iso: "EC",
  name: "Ecuador",
  rate: 34
}, {
  code: 594,
  iso: "GF",
  name: "French Guiana",
  rate: 19
}, {
  code: 595,
  iso: "PY",
  name: "Paraguay",
  rate: 13
}, {
  code: 596,
  iso: "MQ",
  name: "Martinique",
  rate: 19
}, {
  code: 597,
  iso: "SR",
  name: "Suriname",
  rate: 32
}, {
  code: 598,
  iso: "UY",
  name: "Uruguay",
  rate: 9
}, {
  code: 670,
  iso: "TL",
  name: "Timor-Leste",
  rate: 26
}, {
  code: 672,
  iso: "NF",
  name: "Norfolk Island",
  rate: 12
}, {
  code: 673,
  iso: "BN",
  name: "Brunei",
  rate: 7
}, {
  code: 675,
  iso: "PG",
  name: "Papua New Guinea",
  rate: 76
}, {
  code: 676,
  iso: "TO",
  name: "Tonga",
  rate: 22
}, {
  code: 677,
  iso: "SB",
  name: "Solomon Islands",
  rate: 13
}, {
  code: 678,
  iso: "VU",
  name: "Vanuatu",
  rate: 22
}, {
  code: 679,
  iso: "FJ",
  name: "Fiji",
  rate: 22
}, {
  code: 680,
  iso: "PW",
  name: "Palau",
  rate: 24
}, {
  code: 681,
  iso: "WF",
  name: "Wallis and Futuna",
  rate: 11
}, {
  code: 682,
  iso: "CK",
  name: "Cook Islands",
  rate: 14
}, {
  code: 683,
  iso: "NU",
  name: "Niue",
  rate: 24
}, {
  code: 685,
  iso: "WS",
  name: "Samoa",
  rate: 24
}, {
  code: 686,
  iso: "KI",
  name: "Kiribati",
  rate: 15
}, {
  code: 687,
  iso: "NC",
  name: "New Caledonia",
  rate: 18
}, {
  code: 688,
  iso: "TV",
  name: "Tuvalu",
  rate: 30
}, {
  code: 689,
  iso: "PF",
  name: "French Polynesia",
  rate: 18
}, {
  code: 691,
  iso: "FM",
  name: "Micronesia",
  rate: 8
}, {
  code: 692,
  iso: "MH",
  name: "Marshall Islands",
  rate: 16
}, {
  code: 852,
  iso: "HK",
  name: "Hong Kong",
  rate: 8
}, {
  code: 853,
  iso: "MO",
  name: "Macau",
  rate: 11
}, {
  code: 855,
  iso: "KH",
  name: "Cambodia",
  rate: 45
}, {
  code: 856,
  iso: "LA",
  name: "Laos",
  rate: 32
}, {
  code: 880,
  iso: "BD",
  name: "Bangladesh",
  rate: 60
}, {
  code: 886,
  iso: "TW",
  name: "Taiwan",
  rate: 9
}, {
  code: 960,
  iso: "MV",
  name: "Maldives",
  rate: 36
}, {
  code: 961,
  iso: "LB",
  name: "Lebanon",
  rate: 37
}, {
  code: 962,
  iso: "JO",
  name: "Jordan",
  rate: 39
}, {
  code: 964,
  iso: "IQ",
  name: "Iraq",
  rate: 45
}, {
  code: 965,
  iso: "KW",
  name: "Kuwait",
  rate: 32
}, {
  code: 966,
  iso: "SA",
  name: "Saudi Arabia",
  rate: 20
}, {
  code: 967,
  iso: "YE",
  name: "Yemen",
  rate: 30
}, {
  code: 968,
  iso: "OM",
  name: "Oman",
  rate: 22
}, {
  code: 971,
  iso: "AE",
  name: "United Arab Emirates",
  rate: 12
}, {
  code: 972,
  iso: "IL",
  name: "Israel",
  rate: 25
}, {
  code: 973,
  iso: "BH",
  name: "Bahrain",
  rate: 4
}, {
  code: 974,
  iso: "QA",
  name: "Qatar",
  rate: 27
}, {
  code: 975,
  iso: "BT",
  name: "Bhutan",
  rate: 41
}, {
  code: 976,
  iso: "MN",
  name: "Mongolia",
  rate: 30
}, {
  code: 977,
  iso: "NP",
  name: "Nepal",
  rate: 31
}, {
  code: 992,
  iso: "TJ",
  name: "Tajikistan",
  rate: 46
}, {
  code: 993,
  iso: "TM",
  name: "Turkmenistan",
  rate: 33
}, {
  code: 994,
  iso: "AZ",
  name: "Azerbaijan",
  rate: 42
}, {
  code: 995,
  iso: "GE",
  name: "Georgia",
  rate: 17
}, {
  code: 996,
  iso: "KG",
  name: "Kyrgyzstan",
  rate: 46
}, {
  code: 998,
  iso: "UZ",
  name: "Uzbekistan",
  rate: 46
}];

export const SmsCalculator = () => {
  const GSM7_BASIC = new Set(['@', '\u00a3', '$', '\u00a5', '\u00e8', '\u00e9', '\u00f9', '\u00ec', '\u00f2', '\u00c7', '\n', '\u00d8', '\u00f8', '\r', '\u00c5', '\u00e5', '\u0394', '_', '\u03a6', '\u0393', '\u039b', '\u03a9', '\u03a0', '\u03a8', '\u03a3', '\u0398', '\u039e', ' ', '\u00c6', '\u00e6', '\u00df', '\u00c9', ' ', '!', '"', '#', '\u00a4', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '\u00a1', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\u00c4', '\u00d6', '\u00d1', '\u00dc', '\u00a7', '\u00bf', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u00e4', '\u00f6', '\u00f1', '\u00fc', '\u00e0']);
  const GSM7_EXT = new Set(['\f', '^', '{', '}', '\\', '[', '~', ']', '|', '\u20ac']);
  const flagUrl = iso => 'https://flagcdn.com/w40/' + iso.toLowerCase() + '.png';
  const calculate = (text, rate) => {
    let segments = 0;
    let isGsm7 = true;
    let units = 0;
    let limit = 160;
    if (text && text.length > 0) {
      let septets = 0;
      for (const ch of text) {
        if (GSM7_BASIC.has(ch)) septets += 1; else if (GSM7_EXT.has(ch)) septets += 2; else {
          isGsm7 = false;
          break;
        }
      }
      if (isGsm7) {
        units = septets;
        if (septets === 0) {
          segments = 0;
          limit = 160;
        } else if (septets <= 160) {
          segments = 1;
          limit = 160;
        } else {
          segments = Math.ceil(septets / 153);
          limit = 153;
        }
      } else {
        units = text.length;
        if (units <= 70) {
          segments = 1;
          limit = 70;
        } else {
          segments = Math.ceil(units / 67);
          limit = 67;
        }
      }
    }
    return {
      segments,
      total: segments * rate,
      isGsm7,
      units,
      limit
    };
  };
  const fmt = n => Number.isInteger(n) ? n.toString() : parseFloat(n.toFixed(4)).toString();
  const pluralize = (n, w) => n === 1 ? w : w + 's';
  const [selectedIso, setSelectedIso] = useState('US');
  const [text, setText] = useState('Hello! This is a test message to see how the segment calculation works.');
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState('');
  const dropdownRef = useRef(null);
  const searchInputRef = useRef(null);
  const sorted = useMemo(() => [...SMS_COUNTRIES].sort((a, b) => a.name.localeCompare(b.name)), []);
  const selectedCountry = useMemo(() => SMS_COUNTRIES.find(c => c.iso === selectedIso) || SMS_COUNTRIES[0], [selectedIso]);
  const selectedRate = selectedCountry.rate;
  const filtered = useMemo(() => {
    const q = search.toLowerCase();
    return sorted.filter(c => c.name.toLowerCase().includes(q) || c.iso.toLowerCase().includes(q) || ('+' + c.code).includes(search));
  }, [sorted, search]);
  const r = useMemo(() => calculate(text, selectedRate), [text, selectedRate]);
  useEffect(() => {
    if (open) {
      setSearch('');
      const t = setTimeout(() => {
        if (searchInputRef.current) searchInputRef.current.focus();
      }, 10);
      return () => clearTimeout(t);
    }
  }, [open]);
  useEffect(() => {
    const handleClickOutside = e => {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
        setOpen(false);
      }
    };
    if (typeof document !== 'undefined') {
      document.addEventListener('click', handleClickOutside);
      return () => document.removeEventListener('click', handleClickOutside);
    }
  }, []);
  const selectCountry = c => {
    setSelectedIso(c.iso);
    setOpen(false);
  };
  const inSegPos = r.units === 0 ? 0 : (r.units - 1) % r.limit + 1;
  const remaining = r.limit - inSegPos;
  const pct = r.units === 0 ? 0 : Math.min(100, inSegPos / r.limit * 100);
  let progressClass = 'progress-fill';
  if (pct >= 100) progressClass += ' full'; else if (pct > 85) progressClass += ' warn';
  let segmentsMeta = 'No message yet';
  if (r.segments === 1) segmentsMeta = 'Single SMS'; else if (r.segments > 1) segmentsMeta = 'Concatenated SMS';
  let unitsMeta = 'of ' + r.limit + ' in this segment';
  if (r.units !== 0) unitsMeta = remaining + ' left in current segment';
  let encMeta;
  if (r.isGsm7) encMeta = r.segments > 1 ? '7-bit \u00b7 153 chars/segment' : '7-bit \u00b7 160 chars/segment'; else encMeta = r.segments > 1 ? '16-bit \u00b7 67 chars/segment' : '16-bit \u00b7 70 chars/segment';
  const CSS = '.sms-calc-root{--sms-bg:#fff;--sms-surface:#f7f7f7;--sms-ink:hsl(240 10% 3.9%);--sms-ink-soft:hsl(240 3.8% 46.1%);--sms-ink-mute:hsl(240 5% 64.9%);--sms-rule:hsl(240 5.9% 90%);--sms-rule-soft:hsl(240 4.8% 95.9%);--sms-ring:hsl(240 5.9% 10%);--sms-ring-soft:hsl(240 5.9% 10% / .18);--sms-muted:hsl(240 4.8% 95.9%);--sms-green:#15803d;--sms-green-soft:#dcfce7;--sms-amber:#b45309;--sms-amber-soft:#fef3c7;--sms-radius:10px;--sms-radius-card:14px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--sms-ink)}' + '.dark .sms-calc-root,html.dark .sms-calc-root{--sms-bg:#111;--sms-surface:rgba(255,255,255,.025);--sms-ink:#f3f4f6;--sms-ink-soft:#c8c8c8;--sms-rule:rgba(255,255,255,.08);--sms-rule-soft:rgba(255,255,255,.04);--sms-ring:hsl(240 4.9% 83.9%);--sms-ring-soft:hsl(240 4.9% 83.9% / .25);--sms-muted:rgba(255,255,255,.06);--sms-green:#22c55e;--sms-green-soft:#14532d;--sms-amber:#f59e0b;--sms-amber-soft:#451a03}' + '.sms-calc-root *,.sms-calc-root *::before,.sms-calc-root *::after{box-sizing:border-box}' + '.sms-calc-root .wrap{max-width:100%;padding:24px 0}' + '.sms-calc-root .hero-label{font-size:11px;text-transform:uppercase;letter-spacing:1.5px;color:var(--sms-ink-soft);margin-bottom:8px}' + '.sms-calc-root .hero-value{font-weight:700;font-size:48px;line-height:1;letter-spacing:-2px;display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;color:var(--sms-ink)}' + '.sms-calc-root .hero-unit{font-size:16px;font-weight:500;color:var(--sms-ink-soft);text-transform:lowercase}' + '.sms-calc-root .hero-breakdown{margin-top:16px;padding-top:12px;border-top:1px solid var(--sms-rule);font-size:12px;color:var(--sms-ink-soft)}' + '.sms-calc-root .hero-breakdown strong{color:var(--sms-ink);font-weight:600}' + '.sms-calc-root .sms-card{background:var(--sms-surface);border:1px solid var(--sms-rule);border-radius:var(--sms-radius-card);padding:20px;margin-bottom:16px}' + '.sms-calc-root .card-section + .card-section{margin-top:20px;padding-top:20px;border-top:1px solid var(--sms-rule)}' + '.sms-calc-root .field-label{font-size:13px;font-weight:500;color:var(--sms-ink);margin-bottom:8px;display:flex;justify-content:space-between;align-items:center}' + '.sms-calc-root .field-label .help{font-size:11px;font-weight:400;color:var(--sms-ink-mute)}' + '.sms-calc-root .dropdown{position:relative;width:100%}' + '.sms-calc-root .dropdown-selected{width:100%;height:36px;background:transparent;border:1px solid var(--sms-rule);border-radius:var(--sms-radius);padding:4px 12px;font-size:14px;color:var(--sms-ink);cursor:pointer;transition:border-color .15s,box-shadow .15s;display:flex;align-items:center;gap:10px;user-select:none}' + '.sms-calc-root .dropdown-selected.open{border-color:var(--sms-ring);box-shadow:0 0 0 3px var(--sms-ring-soft)}' + '.sms-calc-root .dropdown-selected .arrow{margin-left:auto;transition:transform .2s;color:var(--sms-ink)}' + '.sms-calc-root .dropdown-selected.open .arrow{transform:rotate(180deg)}' + '.sms-calc-root .dropdown-selected img{width:20px;height:14px;object-fit:cover;border-radius:2px}' + '.sms-calc-root .dropdown-list{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--sms-bg);border:1px solid var(--sms-rule);border-radius:var(--sms-radius);box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.06);z-index:1000;display:flex;flex-direction:column;overflow:hidden}' + '.sms-calc-root .dropdown-search{background:var(--sms-bg);padding:0 12px;border-bottom:1px solid var(--sms-rule);display:flex;align-items:center;gap:8px;flex-shrink:0}' + '.sms-calc-root .dropdown-search-icon{width:16px;height:16px;color:var(--sms-ink-mute);flex-shrink:0}' + '.sms-calc-root .dropdown-search input{width:100%;height:44px;background:transparent;border:none;padding:0;font-size:14px;color:var(--sms-ink);outline:none}' + '.sms-calc-root .dropdown-search input::placeholder{color:var(--sms-ink-mute)}' + '.sms-calc-root .dropdown-options{padding:4px;max-height:236px;overflow-y:auto}' + '.sms-calc-root .dropdown-option{padding:6px 8px;display:flex;align-items:center;gap:10px;cursor:pointer;font-size:14px;border-radius:6px;color:var(--sms-ink)}' + '.sms-calc-root .dropdown-option:hover,.sms-calc-root .dropdown-option.selected{background:var(--sms-muted)}' + '.sms-calc-root .dropdown-option img{width:20px;height:14px;object-fit:cover;border-radius:2px;flex-shrink:0}' + '.sms-calc-root .dropdown-option .country-name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}' + '.sms-calc-root .dropdown-option .country-rate{font-size:11px;color:var(--sms-ink-soft);flex-shrink:0}' + '.sms-calc-root .dropdown-option .check-icon{width:16px;height:16px;color:var(--sms-ink);flex-shrink:0;opacity:0;margin-left:4px}' + '.sms-calc-root .dropdown-option.selected .check-icon{opacity:1}' + '.sms-calc-root .dropdown-empty{padding:24px 12px;text-align:center;font-size:13px;color:var(--sms-ink-soft)}' + '.sms-calc-root textarea{width:100%;background:transparent;border:1px solid var(--sms-rule);border-radius:var(--sms-radius);padding:8px 12px;font-family:inherit;font-size:14px;line-height:1.5;color:var(--sms-ink);resize:vertical;min-height:100px;outline:none;transition:border-color .15s,box-shadow .15s}' + '.sms-calc-root textarea:focus{border-color:var(--sms-ring);box-shadow:0 0 0 3px var(--sms-ring-soft)}' + '.sms-calc-root textarea::placeholder{color:var(--sms-ink-mute)}' + '.sms-calc-root .progress-row{margin-top:10px;display:flex;align-items:center;gap:12px}' + '.sms-calc-root .progress-track{flex:1;height:4px;background:var(--sms-rule-soft);border-radius:999px;overflow:hidden}' + '.sms-calc-root .progress-fill{height:100%;background:var(--sms-ink);border-radius:999px;transition:width .25s ease,background .2s}' + '.sms-calc-root .progress-fill.warn{background:var(--sms-amber)}' + '.sms-calc-root .progress-fill.full{background:var(--sms-green)}' + '.sms-calc-root .progress-text{font-size:11px;color:var(--sms-ink-soft);white-space:nowrap}' + '.sms-calc-root .stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}' + '@media (max-width:540px){.sms-calc-root .stats{grid-template-columns:1fr}.sms-calc-root .hero-value{font-size:36px}}' + '.sms-calc-root .stat-label{font-size:11px;color:var(--sms-ink-soft);margin-bottom:4px;font-weight:500;text-transform:uppercase;letter-spacing:.5px}' + '.sms-calc-root .stat-value{font-weight:700;font-size:22px;line-height:1.2;letter-spacing:-.5px;color:var(--sms-ink)}' + '.sms-calc-root .stat-meta{font-size:10px;color:var(--sms-ink-mute);margin-top:2px}' + '.sms-calc-root .sms-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;border-radius:999px;font-size:11px;font-weight:600;letter-spacing:.3px}' + '.sms-calc-root .sms-badge.gsm{background:var(--sms-green-soft);color:var(--sms-green)}' + '.sms-calc-root .sms-badge.ucs{background:var(--sms-amber-soft);color:var(--sms-amber)}' + '.sms-calc-root .sms-badge::before{content:"";width:5px;height:5px;border-radius:999px;background:currentColor}' + '.sms-calc-root .rate-display{margin-top:10px;font-size:13px;color:var(--sms-ink-soft);display:flex;align-items:center;gap:6px}' + '.sms-calc-root .rate-display strong{color:var(--sms-ink);font-weight:600;font-size:15px}';
  return <div className="sms-calc-root">
      <style dangerouslySetInnerHTML={{
    __html: CSS
  }} />
      <div className="wrap">
        <div className="sms-card">
          <div className="card-section">
            <div className="field-label">
              <span>Destination country</span>
              <span className="help">select recipient's country</span>
            </div>
            <div className="dropdown" ref={dropdownRef}>
              <div className={'dropdown-selected' + (open ? ' open' : '')} onClick={() => setOpen(v => !v)}>
                <img src={flagUrl(selectedCountry.iso)} alt={selectedCountry.iso} />
                <span>{selectedCountry.name} (+{selectedCountry.code})</span>
                <svg className="arrow" width="12" height="12" viewBox="0 0 12 12">
                  <path fill="currentColor" d="M6 8L1 3h10z" />
                </svg>
              </div>
              {open && <div className="dropdown-list">
                  <div className="dropdown-search">
                    <svg className="dropdown-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                      <circle cx="11" cy="11" r="8" />
                      <path d="m21 21-4.3-4.3" />
                    </svg>
                    <input ref={searchInputRef} type="text" placeholder="Search country..." value={search} onChange={e => setSearch(e.target.value)} />
                  </div>
                  <div className="dropdown-options">
                    {filtered.length === 0 ? <div className="dropdown-empty">No results found.</div> : filtered.map(c => <div key={c.iso} className={'dropdown-option' + (c.iso === selectedIso ? ' selected' : '')} onClick={() => selectCountry(c)}>
                          <img src={flagUrl(c.iso)} alt={c.iso} />
                          <span className="country-name">{c.name} (+{c.code})</span>
                          <span className="country-rate">{c.rate} cr/seg</span>
                          <svg className="check-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                            <polyline points="20 6 9 17 4 12" />
                          </svg>
                        </div>)}
                  </div>
                </div>}
            </div>
            <div className="rate-display">
              Rate: <strong>{selectedRate}</strong> credit(s) per segment
            </div>
          </div>

          <div className="card-section">
            <div className="field-label">
              <span>Message text</span>
              <span className="help">
                {text.length} {pluralize(text.length, 'character')}
              </span>
            </div>
            <textarea value={text} onChange={e => setText(e.target.value)} placeholder="Type your SMS message here to calculate the cost..." />
            <div className="progress-row">
              <div className="progress-track">
                <div className={progressClass} style={{
    width: pct + '%'
  }} />
              </div>
              <span className="progress-text">
                {r.units} / {r.limit}
              </span>
            </div>
          </div>
        </div>

        <div className="sms-card">
          <div className="card-section">
            <div className="hero">
              <div className="hero-label">Total Cost</div>
              <div className="hero-value">
                <span>{fmt(r.total)}</span>
                <span className="hero-unit">credits</span>
              </div>
              <div className="hero-breakdown">
                <strong>{r.segments}</strong> {pluralize(r.segments, 'segment')} {'\u00d7'}{' '}
                <strong>{fmt(selectedRate)}</strong> {pluralize(selectedRate, 'credit')} each
              </div>
            </div>
          </div>

          <div className="card-section">
            <div className="stats">
              <div className="stat">
                <div className="stat-label">Segments</div>
                <div className="stat-value">{r.segments}</div>
                <div className="stat-meta">{segmentsMeta}</div>
              </div>
              <div className="stat">
                <div className="stat-label">Encoding</div>
                <div className="stat-value" style={{
    marginTop: '2px'
  }}>
                  <span className={'sms-badge ' + (r.isGsm7 ? 'gsm' : 'ucs')}>
                    {r.isGsm7 ? 'GSM-7' : 'UCS-2'}
                  </span>
                </div>
                <div className="stat-meta">{encMeta}</div>
              </div>
              <div className="stat">
                <div className="stat-label">Characters used</div>
                <div className="stat-value">{r.units}</div>
                <div className="stat-meta">{unitsMeta}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>;
};

<div className="block dark:hidden">
  <Frame>
    <div className="p-1">
      <img src="https://mintcdn.com/nlpearl/5m7CLiudjrqxiyho/images/light_mode/action_send_sms.jpg?fit=max&auto=format&n=5m7CLiudjrqxiyho&q=85&s=7442f7ee4d208e4a52cfe5e76fb7f560" alt="Send Email action interface on light mode" className="rounded-[14px]" width="3822" height="2300" data-path="images/light_mode/action_send_sms.jpg" />
    </div>
  </Frame>
</div>

<div className="hidden dark:block">
  <Frame>
    <div className="p-1">
      <img src="https://mintcdn.com/nlpearl/ek92yQlpTyrjmvSe/images/dark_mode/action_send_sms.jpg?fit=max&auto=format&n=ek92yQlpTyrjmvSe&q=85&s=15b33ce6e5ff3eef443535f8175a9900" alt="Send Email action interface on dark mode" className="rounded-[14px]" width="3822" height="2300" data-path="images/dark_mode/action_send_sms.jpg" />
    </div>
  </Frame>
</div>

NLPearl.AI enables your AI agent to send SMS messages during a live conversation. This feature allows for real-time communication, ensuring that your customers receive important information instantly.

***

### Configuring the "Send SMS" Action

To activate and configure the "Send SMS" action within a Pearl, follow these steps:

<Steps>
  <Step title="Navigate to the Call Action Section">
    While creating or editing a Pearl, go to the "Call Action" section.
  </Step>

  <Step title="Click on SMS">
    Select the "SMS" option to activate this functionality for your Pearl.
  </Step>
</Steps>

***

### Fields to Configure

<Steps>
  <Step title="SMS Content">
    **Compose Your Message**: Write the SMS content that you want to be sent out. You can include links, important details, or any relevant information. Additionally, you can use variables within the SMS to personalize the message for each recipient. For example, "Hi `firstName`, your reservation at `restaurantName` is confirmed."
  </Step>

  <Step title="When to Trigger">
    **Trigger Condition**: Describe when you want the SMS to be sent. This could be immediately after a specific event occurs during the conversation. For example, `"Send the SMS immediately after the table reservation is confirmed and processed."`
  </Step>
</Steps>

***

### Example Use Cases

Here are some scenarios where the "Send SMS" action can be effectively used:

<ParamField path="Reservation Confirmations">
  After confirming a reservation, Pearl can automatically send an SMS to the customer with the details.
</ParamField>

<ParamField path="Appointment Reminders">
  Pearl can send a reminder SMS to the customer about an upcoming appointment or event.
</ParamField>

### Regulatory Compliance

To ensure compliance with regulations, Pearl will always ask the third-party customer for their consent before sending an SMS. This step is crucial in respecting the customer's preferences and adhering to communication laws.

***

### SMS Credit Cost

<Info>
  Sending an SMS consumes credits from your account balance. The cost depends on two factors:

  * **Recipient country** : Each destination country has its own rate per segment. International messages cost more than domestic ones.
  * **Number of segments** : A single SMS is limited in character length. Longer messages are automatically split into multiple segments, each billed individually.
</Info>

A standard SMS segment contains up to **160 characters** (GSM-7 encoding). If your message uses special characters or emojis, the encoding switches to UCS-2, reducing the limit to **70 characters** per segment. Messages exceeding one segment are concatenated, with each segment charged separately.

| Encoding               | Single SMS limit | Concatenated segment limit |
| ---------------------- | ---------------- | -------------------------- |
| GSM-7 (standard)       | 160 characters   | 153 characters per segment |
| UCS-2 (unicode/emojis) | 70 characters    | 67 characters per segment  |

When a message exceeds the single SMS limit, a few characters per segment are reserved for concatenation headers, reducing the usable space per segment.

<Warning>
  If your SMS contains **variables** (e.g. `firstName`, `appointmentDate`), the actual total cost may vary. The final number of characters, and therefore segments, depends on the length of each variable's value at the time the message is sent. A short variable like "Tom" uses fewer characters than "Christopher", which could push your message into an additional segment.
</Warning>

### SMS Credit Calculator

Use this calculator to estimate how many segments your message will use and the total credit cost based on the destination country.

<SmsCalculator />

***

<CardGroup cols={1}>
  <Card title="Variables" icon="square-root-variable" iconType="light" href="/pages/variables">
    Learn how to use variables to personalize your SMS content.
  </Card>
</CardGroup>
