Back to blog
Chatmaid Developers··13 min read

Connect Make (Integromat) to WhatsApp, No Meta Verification

Send and receive WhatsApp messages in Make with the HTTP module and a custom webhook, from your own number, with no Meta Business verification.

Chatmaid Team
Connect Make (Integromat) to WhatsApp, No Meta Verification

To connect Make to WhatsApp, use Make's built-in HTTP module to call the Chatmaid API. A POST request to https://developers-api.chatmaid.net/v1/messages/send sends a WhatsApp message from your own number. For the other direction, register a Make custom webhook in Chatmaid, and every message a customer sends you (message.received) lands in your scenario. Chatmaid doesn't have its own Make app as of October 2026, and you don't need one. Chatmaid Developers links your existing WhatsApp number the way WhatsApp Web does, so there is no Meta Business verification. This guide sets up both directions.

What you'll build

By the end of this guide you'll have:

  1. A Make scenario that sends a WhatsApp message when something happens in another app, such as a new row in a spreadsheet, a form submission, a Stripe payment or a Calendly booking.
  2. A Make scenario that receives incoming WhatsApp messages through a webhook, routes them by keyword and replies through Chatmaid.

What you need

  • A Make account. Make's Free plan includes 1,000 credits a month as of October 2026 (see Make's pricing page).
  • A Chatmaid Developers account and an API key. New keys come with the Send Messages (messages:send) and Read Messages (messages:read) scopes, which is all this guide needs. Sandbox keys start with sk_test_, are free, and simulate sends without reaching WhatsApp. Live keys start with sk_live_, send real messages, and need an active subscription.
  • A sender phone. In test mode, add a number in the dashboard and click Connect: it connects instantly, with no QR code. In live mode, you add your real WhatsApp number and scan the QR code with the WhatsApp app on your phone, the same way you link WhatsApp Web.

Each key only sees the phones in its own environment. A test key sends through your test-mode phone, and a live key sends through the number you linked.

Part 1: Send WhatsApp messages from Make

Step 1: Create a scenario and add a trigger

In Make, create a new scenario and choose the trigger that should send the message. For this walkthrough, use Webhooks > Custom webhook so you can send test data yourself. Click Add next to the webhook field, give the webhook a name, click Save and copy the URL Make generates.

Make learns the trigger's fields from the first request it receives. Send it one sample from your terminal, replacing the URL with yours:

curl -X POST "https://hook.make.com/your-webhook-id" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+15557654321",
    "name": "Ana",
    "date": "October 24",
    "time": "3:00 PM",
    "bookingId": "1042"
  }'

Phone numbers must be in E.164 format: a plus sign, the country code and the number, with no spaces or dashes.

Step 2: Add the HTTP module

Click +, search for HTTP and choose Make a request. Fill in these fields:

FieldValue
Authentication typeAPI key
URLhttps://developers-api.chatmaid.net/v1/messages/send
MethodPOST
Body content typeapplication/JSON
Body input methodJSON string
Parse responseYes

Under Credentials, create a keychain for your Chatmaid key:

Keychain fieldValue
NameChatmaid sandbox
KeyBearer sk_test_xxxxxxxxxxxx
API key placementHeader
API key parameter nameAuthorization

The key needs the word Bearer and a space in front of it. You don't add any headers by hand: the keychain sends Authorization, and the body content type sets Content-Type. Make's docs say to keep credentials in the keychain rather than in headers, and it lets you rotate the key in one place later. Make's HTTP app docs and API key keychain guide describe every field.

Step 3: Write the request body

Enter this as the JSON string:

{
  "fromPhoneId": "+15551234567",
  "to": "{{1.phone}}",
  "content": "Hi {{1.name}}, your appointment is confirmed for {{1.date}} at {{1.time}}. Reply here if you need to change it.",
  "idempotencyKey": "booking-{{1.bookingId}}"
}

The {{1.phone}}-style items stand for fields from module 1, the trigger. Don't type them: click in the body and pick each one from Make's mapping panel.

  • fromPhoneId is your sender number in E.164 format. Replace +15551234567 with the number you added in the dashboard. The phone's dashboard ID works too.
  • to is the recipient's number. It also accepts a WhatsApp group ID ending in @g.us, from GET /v1/groups.
  • content is the message text, up to 4,096 characters.
  • idempotencyKey is optional, up to 64 characters. If Make runs the same booking twice, Chatmaid returns the first message instead of sending a second one.

With JSON string, Make drops mapped values in as they are, so you must escape quotes and line breaks yourself. Names and dates are fine. If you map free text, such as a form comment or an AI reply, switch Body input method to Data structure, which escapes values for you. Part 2 uses it.

Step 4: Test with Run once

Click Run once, then send the sample request again. Each time you repeat the test, change bookingId: a used idempotency key always gets the original answer, so a repeated one returns the earlier message instead of sending a new one. A successful send returns HTTP 201:

{
  "success": true,
  "data": {
    "id": "msg_abc123def456",
    "from": "+15551234567",
    "to": "+15557654321",
    "isGroup": false,
    "groupId": null,
    "content": "Hi Ana, your appointment is confirmed for October 24 at 3:00 PM. Reply here if you need to change it.",
    "mediaUrls": [],
    "status": "sent",
    "errorCode": null,
    "errorMessage": null,
    "createdAt": "2026-10-19T14:18:33.000Z",
    "sentAt": "2026-10-19T14:18:33.120Z",
    "deliveredAt": null,
    "readAt": null,
    "failedAt": null
  }
}

Because Parse response is on, these fields appear in Make's mapping panel after the first run. Map the message ID (data.id in the response) into later modules to log it, or to check its status with GET /v1/messages/{id}.

With a sandbox key, the send is simulated and nothing reaches WhatsApp. To send for real, create a second keychain with your sk_live_ key and set fromPhoneId to the number you linked. For the first live test, send to a second phone you own, not to the linked number itself: a message to your own number can be rejected as an invalid recipient. Idempotency keys are shared across your sandbox and live environments, so don't reuse test booking IDs when you go live.

Step 5: Switch the scenario on

Save the scenario and switch it on. With a webhook trigger, it runs whenever data arrives. With a trigger that checks another app for new data, such as a spreadsheet watcher, Make checks on the schedule you set for the scenario.

Part 2: Receive WhatsApp messages in Make

Here's the inbound flow. A customer writes to your WhatsApp number, Chatmaid forwards the message to Make, and your scenario decides what to do. Inbound messages only exist for your linked (live) number. Test-mode phones never receive any, and the reply step needs a live key.

Step 1: Create a custom webhook in Make

Start a new scenario with Webhooks > Custom webhook as the trigger. Click Add, name the webhook, click Save and copy the URL.

Step 2: Register the URL in Chatmaid

In the Chatmaid Developers dashboard, open the Webhooks page:

  1. Paste the Make URL into Webhook URL.
  2. Under Events to receive, tick Message Received.
  3. Click Configure Webhook (it reads Update Webhook if one is already set).
  4. Copy the webhook secret the dashboard shows. It won't be shown again.

Your account has one webhook URL, and every event you tick is sent to it. Saving the Make URL replaces any URL that was there before, so check that nothing else depends on the old one.

Step 3: Give Make a sample payload

Make needs one real request before you can map fields. Either message your connected number from another phone, or post this sample to the Make URL yourself:

curl -X POST "https://hook.make.com/your-webhook-id" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "message.received",
    "timestamp": "2026-10-19T14:21:09.000Z",
    "data": {
      "messageId": "inmsg_abc123def456",
      "from": "+15557654321",
      "to": "+15551234567",
      "content": "STATUS 4892",
      "type": "text",
      "isGroup": false,
      "groupId": null,
      "receivedAt": "2026-10-19T14:21:08.000Z"
    }
  }'

That's the shape Chatmaid sends. from is the customer and to is your connected number. type is one of text, image, video, audio, document, sticker, location, contact or other. For media, content holds the caption, or null when there isn't one.

Don't use the dashboard's Test Webhook button for this step. Its test event is a message.sent with a different data shape, so it would teach Make the wrong fields. If the payload changes later, open the webhook module, click Detect new values and send another sample.

Step 4: Filter and route the messages

Filter. Click the line between the webhook and the next module to add a filter. Let a request through only when {{1.event}} equals message.received and {{1.data.isGroup}} is false. Every event you subscribe to arrives at the same URL, so this keeps delivery receipts and other events out of the reply flow.

Router. Add a Router and give each route a filter on {{1.data.content}}:

  • Contains (case insensitive) "STATUS": order lookup flow
  • Contains (case insensitive) "CANCEL": cancellation flow
  • Fallback route: everything else, for example an AI reply

Make checks routes one after another, and the fallback route takes whatever matches no other route. Give the fallback route a second condition, {{1.data.type}} equal to text, so a photo or voice note without a caption doesn't reach the AI module with an empty prompt.

AI reply. On the fallback route, add an AI module, such as OpenAI, and pass {{1.data.content}} as the customer's message. You'll map its reply text in the next step.

Who the bot answers. message.received fires for every chat on your number, not only customers. If it's also your personal number, don't let the AI answer everyone: put a Google Sheets Search Rows lookup on {{1.data.from}} before the AI module and only reply to numbers on your customer list. If someone also answers from the phone, tick Message Sent From Phone (message.outgoing) on the Webhooks page, record {{1.data.to}} on a separate route for that event, and skip the AI reply for chats a person answered recently. The n8n customer service agent guide shows that pause step in full.

Message order. Make runs incoming webhooks in parallel by default. If a customer sends two messages back to back, the replies can go out in the wrong order. Turn on Process data in order in the scenario settings to handle them one at a time.

Step 5: Reply through Chatmaid

Add another HTTP > Make a request module with the same URL, method and live keychain as in Part 1. This time set Body input method to Data structure. Create a data structure with four text fields (Make can generate one from a sample JSON body), then map them:

FieldValue to map
fromPhoneId{{1.data.to}}
to{{1.data.from}}
contentThe reply text from your AI module
idempotencyKey{{1.data.messageId}}

The fields are swapped on purpose. fromPhoneId takes the webhook's to, the number the customer wrote to, and to takes from, the customer. The data structure escapes quotes and line breaks, which AI replies are full of.

Using the inbound messageId as the idempotency key covers retries. Chatmaid retries a webhook delivery that fails, so the same message can reach Make twice, and the customer still gets one reply.

Chatmaid also signs every delivery with an X-Chatmaid-Signature header. Checking that signature inside Make takes extra work, so treat the Make URL like a password and keep it private. If you need verified requests, receive webhooks on your own server first. The webhook guide shows how to verify them, and the webhooks reference lists every event.

Part 3: Common Make and Chatmaid scenarios

Each of these uses the HTTP module from Part 1 as the send step. Replace each bracketed placeholder with the matching field from your trigger. These templates span several lines, so use the Data structure input method, or write \n for each line break in a JSON string.

Calendly booking to WhatsApp confirmation

Trigger: Calendly > Watch events
Action: HTTP > Make a request (Chatmaid send)

Make's Calendly trigger needs a paid Calendly plan. Your booking form also has to ask for the invitee's phone number in international format. If the trigger's output doesn't include that answer, add Calendly's List event invitees module to fetch it, then map it to to.

Hi [invitee name], your booking is confirmed.

When: [event start time]
Where: [event location]

Need to change it? Just reply to this message.

Stripe payment to WhatsApp receipt

Trigger: Stripe > Watch Events, with the event type checkout.session.completed
Action: HTTP > Make a request (Chatmaid send)

Turn on phone number collection in Checkout. The number arrives in customer_details.phone and the amount in amount_total, in the smallest currency unit, such as cents for USD (Stripe API reference), so divide by 100 for those currencies. Use the session's payment_intent ID (pi_...) as idempotencyKey, not the session ID: Checkout Session IDs are longer than the 64-character limit, and the send would fail with a 400.

Payment received. Thank you!

Amount: [amount] [currency]
For: [description]

Questions about this payment? Reply to this message.

Form submission to welcome message

Trigger: your form tool's watch-new-responses trigger, such as Typeform, Tally or Google Forms
Actions:

  1. HTTP > Make a request: send the welcome message
  2. Google Sheets: add a row to log the contact
  3. Email or Slack: alert your sales team

Ask for the phone number with the country code on the form, and use the response ID as idempotencyKey.

Hi [first name], thanks for getting in touch with [your business].

We got your message about [topic] and will reply here within one business day.

Spreadsheet or Airtable list to WhatsApp outreach

Trigger: new records in Airtable, or new rows in Google Sheets, where Status is "Contact"
Action: HTTP > Make a request (Chatmaid send), with the record ID as idempotencyKey
Post-action: update the record to "Contacted" and store the Chatmaid message ID

The record ID as the key means a contact never gets the same outreach twice, even if the scenario picks the record up again. Only message people who expect to hear from you. If your list lives in a spreadsheet and you'd rather skip Make, see how to send WhatsApp messages from Google Sheets.

Part 4: Error handling in Make

Set up three things on the HTTP module:

  1. Return errors. In the module's advanced settings, set Return error if HTTP request fails to Yes. Then any 4xx or 5xx response raises an error that a handler can act on.
  2. Add a handler. Right-click the module, choose Add error handler and pick Retry. Set Automatically complete execution to Yes, then choose the number of attempts and the interval. The Retry handler only works when Store incomplete executions is set to Yes in the scenario settings (Make's Retry handler docs).
  3. Or skip. For list sends where one bad row shouldn't hold anything up, use the Skip handler instead. It drops the failing bundle and moves on to the next one (overview of Make's error handlers).

Chatmaid's error responses name the problem in an error field and explain it in message. A send that WhatsApp refused also carries the messageId. Here's what each status means for a retry:

StatusMeaningRetry?
400Invalid request (such as a badly formatted phone number), sender phone not connected, invalid recipient, or media that couldn't be fetchedNo. Fix the data or relink the phone.
401Missing or invalid API keyNo. Check the keychain.
403Missing scope, no active subscription for a live key, or the sender can't post in that groupNo. Fix the key, the plan or the group.
404Sender phone not foundNo. Check fromPhoneId and the key's environment.
409NOT_CONNECTED or NOT_AUTHORIZED: the phone's WhatsApp session dropped or expiredNo. Relink the phone first.
422RECIPIENT_NOT_REACHABLE: WhatsApp refused the messageNo.
429Rate limit exceeded: Chatmaid's API rate limitYes, after retryAfter seconds.
429RATE_LIMITED: WhatsApp is throttling the numberLater, with a new idempotency key.
500, 503Unexpected error, or WhatsApp is temporarily unavailableLater, with a new idempotency key.
504TIMEOUT: WhatsApp didn't answer in timeOnly after checking the message didn't arrive.

Retries and idempotency keys work together. Make's Retry handler resends the same body, so the same key, and Chatmaid answers a repeated key exactly as it answered the first time:

  • After Chatmaid's own rate limit (the first 429 row), the retry goes through. Chatmaid turned the request away before it created a message.
  • After a dropped connection, the retry is safe. If the first request did create a message, Chatmaid returns that message instead of sending a second one.
  • After a send WhatsApp refused, every retry with the same key returns the same failure. That's what protects you from double sends. Once you fix the cause, send again with a new key, such as booking-1042-2.

A 504 is the one case where the message may or may not have gone out, so check before sending it again under a new key. The errors reference shows the full error format.

Staying within limits

Make scenarios can fire fast. If a spreadsheet watcher picks up a few hundred new rows at once, they all hit the API in one run.

  • Chatmaid's rate limit is 100 requests a minute by default. Past that, the API returns 429 with a retryAfter value in seconds, and the Retry handler above deals with it.
  • Space out big sends. Add a Tools > Sleep module after the HTTP module to pause a few seconds between messages. Sleep can wait up to 300 seconds (Make's Tools docs).
  • Rehearse with the sandbox. Sandbox sends are simulated, so you can run a whole list with an sk_test_ key without messaging anyone.
  • Protect your number. Only message people who expect to hear from you (see the FAQ on bans below).

As of October 2026, Chatmaid Developers costs $7.99 a month, flat, for production, and the sandbox is free. See pricing. Prefer n8n to Make? The same receive-and-reply loop is built node by node in the n8n customer service agent guide.

Frequently asked questions

Do I need the WhatsApp Business API or Meta verification?

No. Chatmaid links your existing WhatsApp number as a linked device, the way WhatsApp Web does, so there's no Meta Business verification and no template approval.

Can I build this without paying?

You can build and test the sending side for free with a sandbox key, which simulates sends. Real customer messages only reach a linked live number, and replying needs a live key. Both need the $7.99 a month subscription.

Can Make reply in WhatsApp groups?

Yes. Group messages arrive with isGroup set to true and the group's ID in groupId. Remove the isGroup condition from the filter and map to with Make's if() function: {{if(1.data.isGroup; 1.data.groupId; 1.data.from)}}. Your number must be a member of the group and allowed to post in it.

Can I send images or PDFs from Make?

Yes. Add a mediaUrls field to the body with an HTTPS link to the file, and content becomes its caption. With several links, content is sent first as a separate text message. Plain http:// links are rejected.

Why does my Make scenario get a 404 from Chatmaid?

The API can't find the sender phone. Check that fromPhoneId is the full E.164 number, and that it belongs to the same environment as your key: a test-mode phone for an sk_test_ key, your linked number for an sk_live_ key.

Can my WhatsApp number get banned for sending from Make?

It's very unlikely with normal use. WhatsApp restricts accounts that behave like spam, such as unsolicited bulk messages to people who don't have you saved. Confirmations, receipts and replies to customers who wrote first are the normal case.