DEVELOPER GUIDE

How to Send SMS from Node.js with the Grupo Tecnophone API

Send SMS from your Node.js services with native fetch: token authentication, an authorized IP and a JSON response with the ID of each message.

Before you start

  • An API connection created in the web panel (app.grupotecnophone.com), with its Bearer Token for sandbox or production.
  • Your server’s public IP registered as authorized for that token.
  • A User-Agent header that identifies your application, for example MyCompany/1.0.
  • Node.js 18 or later (includes native fetch ). On earlier versions you can use the httpsmodule, as in the official documentation example.

Store the token in an environment variable (in these examples, GTP_SMS_TOKEN) and never include it in the code of a mobile app or website: API calls must always come from your backend, from an authorized IP.

Send an SMS with Node.js

This function sends an SMS and returns the response, or throws an error with the code received. Always use it on the server, never in the browser:

const ENDPOINT = 'https://api.grupotecnophone.com/prod/v1/sms/send';

async function sendSms(to, body) {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.GTP_SMS_TOKEN}`,
      'Content-Type': 'application/json',
      'User-Agent': 'MiEmpresa/1.0',
    },
    body: JSON.stringify({ to, body }),
    signal: AbortSignal.timeout(30_000),
  });

  const data = await res.json().catch(() => ({}));

  if (res.ok && data.status === 'success') {
    return data; // sid, encoding, num_chars, num_segments
  }

  const code = data.error?.code ?? `HTTP_${res.status}`;
  throw new Error(`${code}: ${data.error?.message ?? res.statusText}`);
}

sendSms('+525512345678', 'Your verification code is 482913. It expires in 5 minutes.')
  .then((r) => console.log(r.sid, r.num_segments))
  .catch((err) => console.error(err.message));

API response

If the message was accepted, the API responds with HTTP 200 and a JSON body like this:

{
  "sid": "sms_20261012143201_39bdafbd",
  "status": "success",
  "to": "+525512345678",
  "body": "Your verification code is 482913. It expires in 5 minutes.",
  "encoding": "GSM7",
  "num_chars": 56,
  "num_segments": 1,
  "error": null
}

Store the sid: it is the identifier you will use to reconcile the message’s delivery report. The num_segments field indicates how many segments will be billed; see how segments are calculated.

Send SMS to multiple recipients with Node.js

To send bulk SMS from Node.js, reuse the sendSms function from the previous example and loop through your list. Sending one by one with a short pause avoids spikes and makes it easy to log the sid or the error for each number.

const recipients = ["+525512345678", "+525598765432"];
const message = "Your order 1234 is on its way.";
const pause = (ms) => new Promise((r) => setTimeout(r, ms));

for (const number of recipients) {
  try {
    const r = await sendSms(number, message);
    console.log(number, "->", r.sid);
  } catch (err) {
    console.error(number, "-> error:", err.message);
  }
  await pause(100); // moderate pace for large lists
}

Without coding, you can also send bulk SMS from Excel or CSV.

Send an OTP code with Node.js

Use crypto.randomInt, which is safe for verification codes, and store only the hash of the code.

import { randomInt } from "node:crypto";

const otp = String(randomInt(0, 1_000_000)).padStart(6, "0");
await sendSms("+525512345678", `Your verification code is ${otp}. It expires in 5 minutes.`);
// Store only the code hash and its expiry date

More details on the flow in the guide to SMS OTP authentication.

Common errors

HTTPCodeMeaning
400ENCRYPTION_REQUIREDThe connection requires to and body to be encrypted with RSA-OAEP
400ENCRYPTION_NOT_ALLOWEDThe connection operates in plain text and encrypted content was received
400INPUT_PHONE_BLACKLISTEDThe destination number is on the blacklist
400INSUFFICIENT_BALANCEInsufficient balance for the send
401—Missing or invalid token
403—The source IP is not authorized for the token
500—Unexpected internal error

On 400 errors the response includes an error object with code, code_num and message.

Test in sandbox

Change the endpoint to https://api.grupotecnophone.com/test/v1/sms/send and use the sandbox token. That environment validates the token, IP, payload and encryption with the same logic as production, but does not send real SMS.

Best practices

  • Set a timeout and log each response with its sid.
  • After a network error with no response, do not resend blindly: check first so you don’t duplicate the message to the user.
  • Retry only 500 errors, with progressive backoff and a maximum number of attempts.
  • Queue bulk sends instead of sending them within a web request cycle.
  • If the content is sensitive, enable connection encryption; the API documentation includes an RSA encryption example in PHP without external libraries.

See also the SMS API for Mexico, the SMPP connection and the guides for PHP, Laravel, Python and Java. If you need test credentials, contact us.

FAQ: Sending SMS with Node.js

Scroll to Top