Send Text Message

Use for core text messaging. Required params: instance_id, access_token, chatId, message.

POST
https://api.wawp.net/v2/send/text?access_token=YOUR_ACCESS_TOKEN&chatId=201234567890%40c.us&instance_id=123456789&message=Hi+from+Wawp&reply_to=false_111...AAAA

Authentication Required

Login to swap the placeholders with your real Instance ID and Access Token.

Log In
Test /v2/send/text endpoint
POSTGET

No query parameters required

This endpoint doesn't expect data in the URL.

Best practices

  • Include a clear way for users to opt-out of communications.

  • Use webhooks to track delivery status if your application requires confirmation.

  • Implement a retry strategy with exponential backoff for 'wawp_upstream_error' scenarios.

Narrative Power: Mastering the Core Text Engine

The /v2/send/text endpoint is the most fundamental and frequently used tool in the Wawp arsenal. While it may seem simple to "just send text," this endpoint is powered by a high-performance rendering engine that manages character encoding, markdown parsing, and delivery synchronization. For businesses, this is the primary channel for notifications, support responses, and conversational marketing.

send text.png


🏗️ Technical Architecture of the Text Pipeline

When a POST request hits this endpoint, Wawp initiates a stateless workflow:

  1. Normalization: The chatId is sanitized (removing + or extraneous spaces) and verified against the WhatsApp network routing table.
  2. Text Bufferings: The message string is buffered to prevent memory overflow. WhatsApp supports up to 4,096 characters, and our proxy enforces this limit to ensure upstream delivery remains atomic.
  3. Markdown Pre-processing: Wawp preserves WhatsApp-specific markdown (e.g., *bold*, _italic_, ~strikethrough~, and code blocks). This allows you to send rich, structured text without needing complex HTML or XML wrappers.

🛡️ Strategic Best Practices for Developers

1. The Optimistic UI Pattern

For high-quality user experiences, don't make the user wait for the API response before showing the message in your frontend.

  • Implementation: When the user clicks "Send," immediately render the message in your chat UI with a "Sending..." indicator. Call /v2/send/start-typing a few seconds before the actual POST to mimic human behavior. Once the /send/text returns a message_id, update the UI state to "Sent."

2. Handling Character Complexity

If you are sending technical logs, code snippets, or non-Latin character sets (Arabic, Mandarin, etc.), note that:

  • Encoding: Wawp uses UTF-8 encoding by default. Ensure your application server sends the correct Content-Type: application/json headers to prevent character corruption.
  • Truncation Safety: If your text exceeds 4,000 characters, we recommend splitting it into multiple logical messages or using the CLIP (Copy Link in Profile) strategy to host longer content on a web page.

3. Error Recovery and Upstream Reliability

Occasionally, the WhatsApp network (Upstream) may experience transient lag.

  • The "2xx vs Delivery" Fallacy: A 200 OK from Wawp means the message was successfully accepted and queued for delivery to the engine. It does not guarantee the recipient's phone is on.
  • Monitoring: Always use Webhooks (message.ack) to track when the status moves from "Sent" (1 checkmark) to "Delivered" (2 checkmarks) and finally "Read" (blue checkmarks).

🧩 Advanced Use Cases

Variable Injection and Templating

Because Wawp is stateless, you can easily build a templating engine on your side.

  • Example: "Hi {{name}}, your order #{{order_id}} is ready!"
  • Technique: Perform the string replacement in your backend before sending the final string to Wawp. This keeps the logic localized to your business rules while Wawp handles the heavy lifting of delivery.

Threaded Conversations (Reply-to)

By including the reply_to parameter (the message_id of a previous message), you can create structured threads. This is crucial for:

  • Support systems where the agent needs to clarify a specific customer question.
  • Group chats where multiple topics are being discussed simultaneously.

🛠️ Common Pitfalls and Solutions

  • Forbidden Characters: While emojis are fully supported, stay away from low-level control characters (\x00-\x1F) which can trigger security flags or cause the engine to crash.
  • Empty Messages: Sending an empty message or one consisting only of whitespace will return a 400 Bad Request. Always validate your input fields.
  • Rate Overload: Sending 1,000 text messages to the same user in 60 seconds is a guaranteed "spam" flag. Use a sane "Consumer Protection" delay (minimum 1 second between messages to the same recipient).

Summary of Capabilities:

  • Send structured, rich text with full support for WhatsApp Markdown.
  • High-concurrency support for notification and alert systems.
  • Seamless integration with threading/replies via reply_to.
  • Real-time event tracking through consistent message_id generation.
  • Support for all global languages and emoji sets via UTF-8.

Request Parameters

Configure the parameters required to interact with this endpoint. All query and body arguments are listed below with their details.

Request Body

Sent as a JSON object
string

Unique ID of the WhatsApp session

Example:
string

API access token

Example:
string

Recipient's WhatsApp ID (JID). Supports Individuals (@c.us), Groups (@g.us), and Newsletters (@newsletter).

Example:
string

Message text to be sent

Example:
string

The ID of the message you are replying to

Example:

Request Samples

Use these ready-to-go code snippets to integrate our API into your project quickly and efficiently. Choose your preferred language and library.

1const baseUrl = "https://api.wawp.net";
2const endpoint = "/v2/send/text";
3const params = new URLSearchParams({
4 "instance_id": "123456789",
5 "access_token": "YOUR_ACCESS_TOKEN"
6}).toString();
7const body = {
8 "chatId": "201234567890@c.us",
9 "message": "Hi from Wawp",
10 "reply_to": "false_111...AAAA"
11};
12
13fetch(`${baseUrl}${endpoint}${params ? '?' + params : ''}`, {
14 method: "POST",
15 headers: { "Content-Type": "application/json" },
16 body: JSON.stringify(body)
17})
18 .then(async (response) => {
19 if (response.ok) {
20 const data = await response.json();
21 console.log("Success:", data);
22 return data;
23 }
24
25 // Error Handling
26 if (response.status === 400) {
27 console.error("Error 400: Bad Request - Missing Required Parameter(s)");
28 }
29 if (response.status === 400) {
30 console.error("Error 400: Bad Request - Invalid Number (Egypt)");
31 }
32 if (response.status === 400) {
33 console.error("Error 400: Bad Request - Invalid Number (Saudi Arabia)");
34 }
35 if (response.status === 400) {
36 console.error("Error 400: Bad Request - Invalid Number (Unknown)");
37 }
38 if (response.status === 400) {
39 console.error("Error 400: Bad Request (XML Format)");
40 }
41 if (response.status === 400) {
42 console.error("Error 400: Bad Request (Plain Text)");
43 }
44 if (response.status === 401) {
45 console.error("Error 401: Unauthorized - Invalid or Missing Access Token");
46 }
47 if (response.status === 401) {
48 console.error("Error 401: Unauthorized (XML Format)");
49 }
50 if (response.status === 404) {
51 console.error("Error 404: Not Found - Session Does Not Exist");
52 }
53 if (response.status === 404) {
54 console.error("Error 404: Not Found (XML Format)");
55 }
56 if (response.status === 429) {
57 console.error("Error 429: Too Many Requests - Rate Limit Exceeded");
58 }
59 if (response.status === 500) {
60 console.error("Error 500: Internal Server Error - Unexpected Failure");
61 }
62 if (response.status === 500) {
63 console.error("Error 500: Internal Server Error (HTML)");
64 }
65 if (response.status === 502) {
66 console.error("Error 502: Bad Gateway - Connection Failed to Upstream");
67 }
68 if (response.status === 502) {
69 console.error("Error 502: Bad Gateway (XML Format)");
70 }
71
72 const errorText = await response.text();
73 console.error(`Error ${response.status}: ${errorText}`);
74 })
75 .catch((error) => console.error("Network Error:", error));
Interactive Samples
Ln 75, Col 1javascript

Expected Responses

Explore all possible responses and outcomes from the server. We have documented each status code with data examples to make success and error handling easier.

Message Sent Successfully
Type:
application/json
object *
string *
object *
number *
boolean *
string *
string *
number *
string *
string *
string *
boolean *
number *
boolean *
boolean *
boolean *
boolean *
boolean *
array *
array *
array *
boolean *
array *

Example

{
"_data": {
  "id": {
    "fromMe": true,
    "remote": "000000000000@c.us",
    "id": "MSG_ID_123456",
    "_serialized": "true_000000000000@c.us_MSG_ID_123456"
    },
  "viewed": false,
  "body": "BASE64_IMAGE_DATA",
  "type": "image",
  "t": 1759108866,
  "from": {
    "server": "c.us",
    "user": "111111111111",
    "_serialized": "111111111111@c.us"
    },
  "to": {
    "server": "c.us",
    "user": "000000000000",
    "_serialized": "000000000000@c.us"
    },
  "ack": 0,
  "isNewMsg": true,
  "star": false,
  "kicNotified": false,
  "caption": "Here's your requested image.",
  "deprecatedMms3Url": "https://example.com/media-url",
  "directPath": "/media/direct/path/example",
  "mimetype": "image/jpeg",
  "filehash": "FILE_HASH_PLACEHOLDER",
  "encFilehash": "ENC_FILE_HASH_PLACEHOLDER",
  "size": 192487,
  "mediaKey": "MEDIA_KEY_PLACEHOLDER",
  "mediaKeyTimestamp": 1759108865,
  "streamable": false,
  "mediaHandle": null,
  "isFromTemplate": false,
  "pollInvalidated": false,
  "isSentCagPollCreation": false,
  "latestEditMsgKey": null,
  "latestEditSenderTimestampMs": null,
  "mentionedJidList": {
    },
  "groupMentions": {
    },
  "isEventCanceled": false,
  "eventInvalidated": false,
  "isVcardOverMmsDocument": false,
  "isForwarded": false,
  "isQuestion": false,
  "questionReplyQuotedMessage": null,
  "questionResponsesCount": 0,
  "readQuestionResponsesCount": 0,
  "labels": {
    },
  "hasReaction": false,
  "disappearingModeInitiator": "chat",
  "disappearingModeTrigger": "chat_settings",
  "productHeaderImageRejected": false,
  "lastPlaybackProgress": 0,
  "isDynamicReplyButtonsMsg": false,
  "isCarouselCard": false,
  "parentMsgId": null,
  "callSilenceReason": null,
  "isVideoCall": false,
  "callDuration": null,
  "callCreator": null,
  "callParticipants": null,
  "isCallLink": null,
  "callLinkToken": null,
  "isMdHistoryMsg": false,
  "stickerSentTs": 0,
  "lastUpdateFromServerTs": 0,
  "invokedBotWid": null,
  "bizBotType": null,
  "botResponseTargetId": null,
  "botPluginType": null,
  "botPluginReferenceIndex": null,
  "botPluginSearchProvider": null,
  "botPluginSearchUrl": null,
  "botPluginSearchQuery": null,
  "botPluginMaybeParent": false,
  "botReelPluginThumbnailCdnUrl": null,
  "botMessageDisclaimerText": null,
  "botMsgBodyType": null,
  "requiresDirectConnection": false,
  "bizContentPlaceholderType": null,
  "hostedBizEncStateMismatch": false,
  "senderOrRecipientAccountTypeHosted": false,
  "placeholderCreatedWhenAccountIsHosted": false,
  "galaxyFlowDisabled": false,
  "links": {
    }
  },
"mediaKey": "MEDIA_KEY_PLACEHOLDER",
"id": {
  "fromMe": true,
  "remote": "000000000000@c.us",
  "id": "MSG_ID_123456",
  "_serialized": "true_000000000000@c.us_MSG_ID_123456"
  },
"ack": 0,
"hasMedia": true,
"body": "Here's your requested image.",
"type": "image",
"timestamp": 1759108866,
"from": "111111111111@c.us",
"to": "000000000000@c.us",
"deviceType": "android",
"isForwarded": false,
"forwardingScore": 0,
"isStatus": false,
"isStarred": false,
"fromMe": true,
"hasQuotedMsg": false,
"hasReaction": false,
"vCards": {
  },
"mentionedIds": {
  },
"groupMentions": {
  },
"isGif": false,
"links": {
  }
}
Bad Request - Missing Required Parameter(s)
Unauthorized - Invalid or Missing Access Token
Not Found - Session Does Not Exist
Too Many Requests - Rate Limit Exceeded
Internal Server Error - Unexpected Failure
Bad Gateway - Connection Failed to Upstream
Previous TopicMessaging Guide
Next TopicSend Image

Command Palette

Search for a command to run...