Skip to main content
Version: v0.23.1

Manage the business profile and product catalog

Two WhatsApp business surfaces exist in the API: the business profile — the display name, about text, and profile picture WhatsApp shows next to your number — and the product catalog — the shopfront of product cards a business can send in chats. The profile endpoints work on both engines; catalog reads and product-card sends work on the Baileys engine (since v0.13.0), while whatsapp-web.js — which has no catalog API — still returns 501 Not supported for every catalog call.

This guide shows you how to update the profile fields, and how to read and send from the catalog on a Baileys session.

Prerequisites

All examples use these placeholders. Set them once in your shell:

export BASE="http://localhost:2785/api" # /api is the global prefix; behind your domain + TLS in production
export API_KEY="YOUR_API_KEY" # an operator-or-higher key, from your dashboard
export SESSION="8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a" # the UUID id of a ready session

Update the display name

PUT /api/sessions/{sessionId}/profile/name sets the account display name, capped at 25 characters (WhatsApp's limit).

curl -X PUT "$BASE/sessions/$SESSION/profile/name" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "OpenWA Store"}'

A 200 means the name was accepted. 400 means the session is not started; 403 means the engine refused the change.

Update the about/status text

PUT /api/sessions/{sessionId}/profile/status sets the about text shown on the profile. It may be empty to clear it, and is capped at 139 characters (WhatsApp's limit).

curl -X PUT "$BASE/sessions/$SESSION/profile/status" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "We reply within a day."}'

A 200 means the status was accepted; 400 means the session is not started.

Update the profile picture

PUT /api/sessions/{sessionId}/profile/picture sets the profile picture from either an image url or inline base64 data. When sending base64, mimetype is required (for example image/jpeg).

From a URL:

curl -X PUT "$BASE/sessions/$SESSION/profile/picture" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/store-logo.jpg"}'

From base64 data:

curl -X PUT "$BASE/sessions/$SESSION/profile/picture" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"base64": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wB...",
"mimetype": "image/jpeg"
}'

DELETE /api/sessions/{sessionId}/profile/picture removes the picture again. It takes no request body:

curl -X DELETE "$BASE/sessions/$SESSION/profile/picture" \
-H "X-API-Key: $API_KEY"

A 200 carries {"success": true, "message": "Profile picture removed"}. Removing a picture that is already absent is a no-op that also answers 200, so the call is safe to repeat. Both verbs work on both engines — unlike the catalog routes below, neither returns 501.

Error responses:

StatusMeaning
400Neither url nor base64 provided, base64 without mimetype, or the session is not started
403The engine refused the picture change, or refused the removal
413The decoded base64 image exceeds the configured media cap (PUT only)
503On a DELETE, WhatsApp did not answer within the request budget — the removal may or may not have applied

Read the catalog (Baileys engine)

Since v0.13.0, the catalog reads are implemented on the Baileys engine. A whatsapp-web.js session has no catalog API, so every catalog call on it still returns 501 Not supported by the active engine.

GET /api/sessions/{sessionId}/catalog returns the catalog metadata:

curl "$BASE/sessions/$SESSION/catalog" \
-H "X-API-Key: $API_KEY"

The metadata is synthesized from the first collection; a business without collections gets null.

GET /api/sessions/{sessionId}/catalog/products lists the products, with page/limit pagination:

curl "$BASE/sessions/$SESSION/catalog/products?page=1&limit=10" \
-H "X-API-Key: $API_KEY"

The engine walks the library's cursor-based catalog in full and slices page/limit in memory, so pagination.total and pagination.totalPages are exact rather than estimated.

Fetch a single product with GET /api/sessions/{sessionId}/catalog/products/{productId}:

curl "$BASE/sessions/$SESSION/catalog/products/product-42" \
-H "X-API-Key: $API_KEY"

A 200 returns the product; an unknown id comes back 404.

Send a product card

POST /api/sessions/{sessionId}/messages/send-product resolves the product from the catalog and sends it as a native product card:

curl -X POST "$BASE/sessions/$SESSION/messages/send-product" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chatId": "628123456789@c.us",
"productId": "product-42",
"body": "Back in stock!"
}'

chatId and productId are required; body is optional text accompanying the card. Error responses:

StatusMeaning
400The product has no image — the card cannot render without one
404Unknown productId
501Called on a whatsapp-web.js session
send-catalog was removed in v0.19.0

POST /api/sessions/{sessionId}/messages/send-catalog always answered 501 — neither library has a catalog-share message type — so v0.19.0 removed the route entirely. A call to the old URL now gets a 404. Sending a full catalog grid is not available anywhere; send a product card with send-product, or share a product link as text.

Troubleshooting

ProblemCauseFix
400 Session is not startedSession is not in a ready stateStart the session, then retry
403 The engine refused the name changeWhatsApp rejected the value (for example, an unavailable name)Retry with a different value
413 on picture uploadDecoded base64 image exceeds the media capCompress the image or raise the media cap
501 Not supported on catalog callsSession runs on the whatsapp-web.js engine (no catalog API)Use a Baileys session for catalog reads and send-product
404 on send-catalogThe route was removed in v0.19.0 — it never worked on any engineSend a product card with send-product, or share a product link as text

Next steps