Skip to content
WaaruDocs

Send WhatsApp messages with the Waaru SDK for Node.js

Install @waaru/sdk, configure a server-side API key, send WhatsApp text or approved templates, and understand queued responses and safe error handling.

Reviewed

Waaru SDK for Node.js sends WhatsApp text messages and approved templates from your server. Install the official @waaru/sdk package on npm. The official website is Waaru.

This guide was checked against published 1.0.0-beta.2 on 12 September 2026. The SDK requires Node.js 22.14 or later. Installation does not confirm API or sender readiness.

Before you start

  1. Create a workspace and connect your WhatsApp number.
  2. Follow Developer API setup. Choose Use Developer API for that number in Settings > Developer > API keys. This is EXTERNAL_API mode in the API contract.
  3. Create a key with messages:send. Add messages:read to check outcomes through REST, and media:read only for REST attachment downloads. See API key scopes.
  4. Choose a separate WhatsApp account you control or have permission to test with.

Each key is permanently bound to one sending number. Rotating it does not change the sender. Use a separate key/client for another number; there is no from option.

Developer API mode stops Logic Flow and automatic replies for that number. Incoming messages remain visible in Inbox. A failed callback does not start a Logic Flow as a fallback. Switching back stops new Developer API requests and callbacks, including reads. It does not cancel already accepted sends.

If a teammate takes ownership of a conversation, API sends pause. An authorized teammate must review it and select Release to API when the integration should resume.

Install and keep the key on your server

npm install @waaru/[email protected]

The command pins the version used for these examples.

Create .env locally and replace the placeholders. Use a permitted test number with a leading + and country code.

WAARU_API_KEY=replace_with_your_server_api_key
WAARU_TEST_RECIPIENT=replace_with_your_permitted_test_number

Add .env to .gitignore. Use your deployment’s secret store when hosting the integration. Never put this key in browser code, a NEXT_PUBLIC_ variable, logs, or a support request.

new Waaru() reads WAARU_API_KEY. Its default origin is https://api.waaru.app; the SDK adds /v1/messages.

Send a text reply

First send a message from the test account to your business number. The customer-service window lasts 24 hours after that account’s latest message to the number. Text replies require an open window and must pass the other messaging checks.

Save as send-text.mjs:

import Waaru, { WaaruApiError, WaaruConnectionError } from "@waaru/sdk";

const to = process.env.WAARU_TEST_RECIPIENT;
if (!to) throw new Error("Set WAARU_TEST_RECIPIENT to your test account.");
const waaru = new Waaru();

try {
  const accepted = await waaru.messages.sendText({
    to,
    text: "Thanks for your test message.",
  });
  console.log({
    status: accepted.status,
    messageId: accepted.messageId,
    requestId: accepted.requestId,
  });
} catch (error) {
  if (error instanceof WaaruApiError) {
    console.error({
      status: error.status,
      code: error.code,
      requestId: error.requestId,
      retryAfterSeconds: error.retryAfterSeconds,
      outcomeUnknown: error.outcomeUnknown,
    });
  } else if (error instanceof WaaruConnectionError) {
    console.error(
      "Connection interrupted. Check the outcome before resending.",
    );
  } else {
    console.error("Check the SDK setup and message fields. No retry was made.");
  }
  process.exitCode = 1;
}

After checking the recipient and prerequisites, run:

node --env-file=.env send-text.mjs

Expected result: HTTP 202 produces status: "queued" and a Waaru messageId. This means the request was accepted for processing, not delivered. Record the message ID to read its status through REST or match signed webhook events. Confirm receipt on the test phone.

Send an approved template

Use an eligible approved template to start a conversation or message outside the service window. Create and review the template in the dashboard first. Its exact name, language code, and parameters must match the approved template for the key’s WhatsApp Business Account.

This example uses approved template order_update, language en_US, with one positional body text parameter. These values are illustrative; the SDK does not supply this template. Replace them to match your own approved test template.

Save as send-template.mjs:

import Waaru from "@waaru/sdk";

const to = process.env.WAARU_TEST_RECIPIENT;
if (!to) throw new Error("Set WAARU_TEST_RECIPIENT to your test account.");
const waaru = new Waaru();

const accepted = await waaru.messages.sendTemplate({
  to,
  name: "order_update",
  language: "en_US",
  components: [
    {
      type: "body",
      parameters: [{ type: "text", text: "TEST-ORDER" }],
    },
  ],
});
console.log({ status: accepted.status, messageId: accepted.messageId });
node --env-file=.env send-template.mjs

Omit components for a template without parameters. For positional parameters, keep the approved order. For a named text parameter, include its exact parameter_name alongside type and text. Other components must match the approved template and supported API fields. Not every button configuration is supported. See template request formats.

Template approval does not bypass consent, opt-outs, number restrictions, quality checks, sending limits, or human ownership. Use the text example’s error handling for template sends.

Understand SDK and REST coverage

TaskSDK 1.0.0-beta.2
Send textmessages.sendText
Send an approved templatemessages.sendTemplate
Read status or conversationsREST only
Download attachmentsREST only
Receive and verify callbacksFollow the REST webhook guide

Do not call messages.get() or import a webhook verifier from this beta. Template management, broadcasts, uploads, raw Meta proxying, and client idempotency are not SDK features. See the five REST endpoints. Dashboard routes are not automatically public APIs.

The SDK is MIT-licensed. That license covers the package, not the Waaru platform. There is no paid-only SDK access gate. Platform access is free; optional AI and Meta messaging charges are separate.

Troubleshoot without duplicate sends

The SDK makes zero automatic POST retries. Its default timeout is 30 seconds. A timeout, interrupted connection, or invalid success response can leave the send outcome unknown. Do not rerun the script until you have checked message status, conversation history, or callbacks.

In beta.2, WaaruApiError.outcomeUnknown flags uncertain HTTP outcomes, including 408, server errors, and unrecognized error responses. When it is true, check the outcome before resending. A known rejection can set it to false; fix the reported problem before considering another attempt. There is no client idempotency key; a request ID helps investigation but does not prevent duplicate sends. You may pass a random, non-sensitive requestId in the method’s second argument. Beta.2 retains that caller ID on transport errors and ignores invalid response request-ID headers.

  • invalid_api_key or unauthorized: check environment loading and key rotation or revocation.
  • insufficient_scope: check the key’s permissions.
  • instance_not_api_managed: review Developer API handling for the number.
  • conversation_owned_by_human: ask the authorized teammate to review Inbox ownership.
  • service_window_closed: use an eligible approved template instead of retrying text.
  • Template or quality errors: check name, language, approval, number connection, and quality in the dashboard.
  • 429 or rate_limited: reduce request frequency and respect retryAfterSeconds when supplied. Do not add a blind resend loop.
  • Long-lived queued: inspect REST status and callback processing before sending again.

For account-specific help, open Help and support > Waaru Care > Talk to support in the Waaru dashboard. Follow Waaru Care. For general setup enquiries, use Contact.

Share SDK/Node versions, operation, UTC time, HTTP status, error code, outcomeUnknown, and request ID. Leave out API keys, signing secrets, phone numbers, customer messages, and template values.

Next: Read message outcomes or receive signed callbacks.

On this page