To request a link preview in a WhatsApp Cloud API text message, put the URL in text.body and set text.preview_url to true. Send that text object with a bearer token to the phone-number ID’s /messages endpoint. A successful API response confirms that WhatsApp accepted the message; it does not guarantee that every recipient or WhatsApp client will render the same preview card.
The request you need
Meta’s documented pattern is a POST request to https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/messages. Replace {{Version}}, {{Phone-Number-ID}}, and the recipient placeholder with values from your own Cloud API setup. The request must use JSON and bearer-token authorization.
POST https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/messages
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"messaging_product": "whatsapp",
"to": "{{Recipient-Phone-Number}}",
"type": "text",
"text": {
"preview_url": true,
"body": "Please visit https://youtu.be/hpltvTEiRrY to inspire your day!"
}
}
The same payload appears in Meta’s Send Text Message with Preview URL example. The URL is ordinary text inside body; there is no separate preview-URL field.
Prerequisites and identifiers
You need a Meta business portfolio, a WhatsApp Business Account, and a business phone number. The phone-number ID in the path identifies the number that sends the message; it is not the recipient’s phone number. The to value identifies the recipient.
Recommended Free Tools
#1 Best Overall
Authenticate with an access token in the Authorization: Bearer header. Meta’s Cloud API collection distinguishes user and system-user tokens: the collection says user tokens expire after 24 hours, while system-user tokens can last up to 60 days or permanently. Confirm the current token rules in Meta’s setup flow before deploying, because token availability and permissions are operational details that can change.
Send a preview message with cURL
This command is runnable from a shell after you substitute your own values. Keep the token out of source control and shell history where your environment permits.
curl -X POST "https://graph.facebook.com/{{Version}}/{{Phone-Number-ID}}/messages"
-H "Authorization: Bearer ACCESS_TOKEN"
-H "Content-Type: application/json"
-d '{
"messaging_product": "whatsapp",
"to": "{{Recipient-Phone-Number}}",
"type": "text",
"text": {
"preview_url": true,
"body": "Please visit https://youtu.be/hpltvTEiRrY to inspire your day!"
}
}'
Use a complete URL beginning with http:// or https:// in the text. The Meta-hosted SDK reference describes body as text that may contain either scheme.
Python example
With Python’s requests library, send the same JSON structure and inspect the HTTP result before treating the operation as accepted.
Rank #2
import requests
version = "{{Version}}"
phone_number_id = "{{Phone-Number-ID}}"
access_token = "ACCESS_TOKEN"
recipient = "{{Recipient-Phone-Number}}"
url = f"https://graph.facebook.com/{version}/{phone_number_id}/messages"
payload = {
"messaging_product": "whatsapp",
"to": recipient,
"type": "text",
"text": {
"preview_url": True,
"body": "Please visit https://youtu.be/hpltvTEiRrY to inspire your day!",
},
}
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
}
response = requests.post(url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Node.js example
The built-in fetch available in current Node.js releases can post the payload without an additional SDK.
const version = '{{Version}}';
const phoneNumberId = '{{Phone-Number-ID}}';
const accessToken = 'ACCESS_TOKEN';
const recipient = '{{Recipient-Phone-Number}}';
const response = await fetch(
`https://graph.facebook.com/${version}/${phoneNumberId}/messages`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to: recipient,
type: 'text',
text: {
preview_url: true,
body: 'Please visit https://youtu.be/hpltvTEiRrY to inspire your day!'
}
})
}
);
if (!response.ok) {
throw new Error(`${response.status}: ${await response.text()}`);
}
console.log(await response.json());
How to read the response
Meta’s example success response contains messaging_product, a contacts array, and a messages array with an ID such as wamid.ID. Treat that ID and the successful HTTP response as evidence that the API accepted the send request. They are not evidence that the recipient opened the conversation, saw the message, or received a particular preview design.
Store the returned message ID with your application’s send log. If the request fails, retain the HTTP status and error body for diagnosis, but redact access tokens and personal data from logs.
What the preview flag does
| Setting | Payload behavior | What is established |
|---|---|---|
true |
Include preview_url: true inside the text object and place the URL in text.body. |
The request asks WhatsApp to include a preview box. |
false or omitted |
Do not enable the documented preview option. | The cited example does not establish how every client will display the resulting plain text. |
The archived Meta-hosted Node.js SDK describes the boolean this way: “if a link is in the text, setting this field to true includes a preview box with more information about the link.” Prefer the current, versioned Cloud API documentation for production implementation because that SDK project is archived.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rendering limits you should plan for
The API request controls whether a preview is requested; it does not give your application control over the recipient’s interface. The documented example does not promise identical rendering across recipients or clients, and a returned message ID does not prove that a card appeared.
The available material also does not establish website metadata requirements, image dimensions, page-fetch timing, image-selection rules, preview caching, or a procedure for forcing a refresh. Do not assume that adding a particular Open Graph tag, changing an image size, or waiting for a cache expiry is a documented fix. If a preview is important to a campaign, test the exact URL and message with the client versions and accounts your audience uses, then provide useful plain-text context so the link remains understandable without a card.
Common failures and fixes
Authentication or permission errors
Check that the header is exactly Authorization: Bearer ACCESS_TOKEN, that the token belongs to the business assets you are using, and that it has not expired. Reissue or rotate the token through the current Meta setup flow rather than embedding a replacement in application code.
Wrong endpoint or phone-number ID
The path must contain the API version and the sending phone-number ID before /messages. A WhatsApp Business Account ID, display phone number, or recipient number in that path is not interchangeable with the phone-number ID shown in your Cloud API configuration.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #4
The message sends but no preview appears
Confirm that the URL is literally present in text.body and that preview_url is a JSON boolean true, not the string "true". If both are correct, the API request is configured as documented, but client rendering is not guaranteed. Compare the result in the recipient clients you support; the cited sources do not identify a universal metadata or image fix.
Malformed JSON or an unexpected URL
Let your HTTP library serialize the object where possible, as in the Python and Node.js examples. Escape quotes and backslashes in generated message text, and validate that the final body contains the complete scheme and host. In shell scripts, quote the JSON argument so the shell does not interpret punctuation before it reaches Graph API.
Following an old SDK sample
The Meta-hosted Node.js SDK reference is explicitly archived. Its field names explain the payload, but version-specific endpoint, authentication, and setup guidance should come from the current WhatsApp Cloud API documentation.
Operational checklist
- Keep the access token in a secret manager or protected environment variable.
- Construct the endpoint from the currently supported Graph API version and the sending phone-number ID.
- Send
Content-Type: application/jsonand a bearer token. - Put the URL in
text.body; settext.preview_urlto the JSON booleantrue. - Record the HTTP result and returned message ID without logging secrets.
- Test the complete message in the recipient clients that matter to your audience.
- Keep plain-text wording useful even when a preview card is not rendered.
Or skip the browser setup
If you need to inspect the linked page itself for campaign or support QA, ScreenshotNeo can return a page image or PDF through one API call; it does not replace WhatsApp’s preview flag or guarantee how WhatsApp renders a card. Its clean-capture steps accept consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture, with each step switchable. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the page verdict and billing result in X-Page-Verdict and X-Billed headers. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo documentation for parameters and authentication. A minimal call is:
Best Value
- The Microsoft Office 365 Bible: The Most Updated and Complete Guide to Excel, Word, PowerPoint, Outlook, OneNote, OneDrive, Teams, Access, and Publisher from Beginners to Advanced
- ABIS BOOK
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo includes 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 screenshots, and every feature is available on every plan. Create a free ScreenshotNeo account when you want to check the destination page without setting up a browser.
Frequently asked questions
Can one message contain more than one link?
The SDK description says body may contain URLs, but the cited example covers one URL and does not specify how multiple URLs are selected or rendered. If multiple destinations matter, test your exact text with the recipient clients you support.
Does the API response tell me whether a preview card was displayed?
No. The documented success response provides acceptance details and a message ID. It does not report what a recipient’s client rendered.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Which documentation should I use for a new integration?
Use Meta’s current, versioned WhatsApp Cloud API documentation and setup flow. The Node.js SDK reference is useful for explaining the field, but the project is archived.
Frequently Asked Questions
Can one message contain more than one link?
The SDK description says body may contain URLs, but the cited example covers one URL and does not specify how multiple URLs are selected or rendered. Test your exact text with the recipient clients you support.
Does the API response tell me whether a preview card was displayed?
No. The documented success response provides acceptance details and a message ID, not the recipient client’s rendered result.
Which documentation should I use for a new integration?
Use Meta’s current, versioned WhatsApp Cloud API documentation and setup flow; the Node.js SDK reference is archived.
Free tools Windows power users keep installed
One-click scans. No signup required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

