Shell integration
Send WhatsApp messages with cURL
A complete, runnable cURL example for sending WhatsApp messages through the SPWP REST API. There is no SDK to install — cURL talks to the API over ordinary HTTP, so you can paste this straight into an existing project.
About 5 minutes to your first delivered message
1. Setup
Create an API key in the dashboard under Accounts → your account → API keys, then make it available to your cURL code as an environment variable. Never commit the key or ship it in client-side code.
# Nothing to install — curl ships with macOS and most Linux distros.
# Keep your key in the environment rather than pasting it into commands.
export SPWP_API_KEY="wak_live_your_key_here"2. Send a text message
One POST with a recipient and a body. The API replies 202 Accepted with a message id in QUEUED state; delivery happens asynchronously and you can track it by id or webhook.
curl -X POST https://api.spwp.app/api/v1/public/messages/text \
-H "X-API-Key: $SPWP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "9647503505440",
"text": "Your verification code is 482310"
}'3. Send an image, document or other media
Media endpoints take the same shape, with a source that is either a public HTTPS URL we fetch server-side or a base64 data URL you upload inline. Swap the path segment for video, audio, document or location.
curl -X POST https://api.spwp.app/api/v1/public/messages/image \
-H "X-API-Key: $SPWP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "9647503505440",
"source": "https://example.com/invoice-3214.png",
"caption": "Your invoice for May"
}'4. Receive replies and delivery receipts
Inbound messages and status changes arrive as signed POSTs to your webhook URL. Recompute the HMAC over the timestamp and the raw request body — re-serialised JSON will not match — and reject anything older than five minutes.
# Recompute the signature over "<timestamp>.<raw body>" and compare.
TS="$X_WA_TIMESTAMP"
BODY="$(cat request-body.json)"
printf '%s.%s' "$TS" "$BODY" \
| openssl dgst -sha256 -hmac "$SPWP_WEBHOOK_SECRET" -hexError handling
Errors carry a non-2xx status and a stable code string you can branch on: VALIDATION_FAILED, INVALID_API_KEY, ACCOUNT_NOT_CONNECTED, RATE_LIMITED, MEDIA_FETCH_FAILED. Retry on 429 while honouring Retry-After; treat 401 as a configuration problem rather than a transient one.
Next steps
The full reference covers every endpoint, field and error code, plus the webhook payload shapes.