Skip to main content
Migrate your WhatsApp numbers from Twilio to Kapso.

Step 1: Connect your number

  1. In WhatsApp Manager, check the WABA for other numbers, templates, or assets you still need.
  2. Turn off two-step verification, under Phone numbers → Settings → Two-step verification, or re-registration will ask for a PIN.
  3. Remove the phone number from the WABA. Leave the WABA itself in your Business Portfolio.
  4. Wait about 10 minutes.
  5. In Kapso, start embedded signup. Create a new WABA when the flow asks.
  6. Recreate your templates on the new WABA (see Step 5). Wait for Meta review.
The number stops sending after step 3, and it can send templates again once Meta approves them on the new WABA. Plan the migration accordingly. See Connect WhatsApp for the signup flow. If embedded signup fails with 2655093, or Meta blocks a billing change over a pending balance, the WABA is still tied to another partner, most often through Twilio’s credit line. In Meta WhatsApp account settings, open the WABA’s Summary → Payment method. If it shows a Credit line from Twilio, ask Twilio to revoke its allocation for this WABA and confirm when it is done. Disconnecting, or disappearing from Partners, does not revoke it. Revoking changes billing for every number on that WABA. If the error remains after one retry, contact Kapso Support to escalate to Meta. A different number on a new WABA unblocks you in the meantime. See recovery steps.
On coexistence? The pairing with the WhatsApp Business app is exclusive to one provider. Do step 1, ask Twilio to revoke its credit line for the number’s WABA (see above), and disconnect Twilio in the app under Settings → Account → Business Platform if it is listed. Revoking changes billing for every number on that WABA, so if others still use Twilio’s billing, move them or give them replacement billing first. Do not remove the number or the WABA. Wait about 10 minutes, then connect through Kapso’s WhatsApp Business App flow. Coexistence always creates a new WABA, so recreate your templates. If it fails, see coexistence troubleshooting.
If the reconnect fails, see coexistence troubleshooting. You can also start on a fresh number. Instant setup gives you a pre-verified US number, with no SMS verification step.
Testing first? The sandbox replaces Twilio’s join <code> flow. Create a session for your test phone, then send the 6-character code from WhatsApp. You can then send and receive without a production number.

Step 2: Get your phone number IDs

Store the mapping from whatsapp:+E164 to phone_number_id. Two IDs address different things: Templates belong to the WABA, not to a number, so every number on that WABA can send them. That is why the template endpoints take the WABA ID in the path, as in POST /{waba_id}/message_templates.

Step 3: Update message sending

For every message type, Kapso uses one endpoint: POST /{phone_number_id}/messages. The type field says which kind of message you are sending, and a field of that same name carries the content. A text message sets type: "text" and puts the body in text.
Business-initiated sends, outside the 24-hour window. ContentSid becomes the template name, ContentVariables becomes Meta’s components array.Twilio:
Kapso:
Parameters are positional and must match the placeholder order. Named parameters work too. See Simple text templates.
The TypeScript SDK wraps all of this, so you do not have to write the envelopes by hand.

Step 4: Update webhooks

Kapso posts JSON and expects a 200. There is no TwiML, so auto-replies move into your handler or into a workflow. Register per phone number:
For connection lifecycle events (a customer finishing a setup link, Meta disabling a WABA), use project webhooks instead. You configure those once for the whole project.

Field mapping

conversation threads the messages for you, but it does not track the 24-hour window. A send can fail with 131047 while conversation.status is active. Read conversation.kapso.last_inbound_at, or handle the rejection and fall back to a template. from is not always present. WhatsApp can identify a contact with business_scoped_user_id instead. See business-scoped user IDs.

Signature verification

Twilio signs the request URL plus every form field, so verification needs all of them. Twilio’s helper assembles them for you. Kapso signs only the request body. Verification is one HMAC over the bytes you received. Twilio:
Kapso:
No URL goes into the hash, so your endpoint can move or sit behind a proxy without breaking verification.

Delivery behavior

Delivery is at-least-once. Dedupe on X-Idempotency-Key. See Advanced for buffering and ordering, and Security for verification in Python and Ruby.
Do you parse raw Meta payloads elsewhere? Register the webhook with "kind": "meta" and Kapso forwards Meta’s exact payload with no reshaping.

Step 5: Templates

Twilio needs two calls: create the content, then request WhatsApp approval. Kapso submits on create. Twilio:
Kapso:
The path takes the WABA ID, not the phone number ID. If you build templates in WhatsApp Manager, pull them into Kapso from WhatsApp → Templates → Sync from WhatsApp. See Template lifecycle.

Multi-tenant setups

Twilio subaccounts become customers, and each customer connects their own number through a setup link instead of you provisioning a sender per subaccount:
Send your customer the returned url. They log in with Facebook and connect in about five minutes. You then get whatsapp.phone_number.created on your project webhook, with the customer.id and phone_number_id. See Onboard customers and Connection detection. One API key covers every customer, so there is no per-subaccount credential juggling.

Bulk sends

If you loop over recipients yourself, or drive bulk sends from Studio, use broadcasts instead. Create, add recipients with per-recipient template parameters, send, poll:
Kapso paces broadcasts internally to stay inside Meta’s throughput limits, so you do not throttle them yourself. POST /{id}/schedule sends later, POST /{id}/cancel stops one in flight.

Keep your Twilio account for numbers

You do not have to leave Twilio to leave Twilio’s WhatsApp API. Point Kapso at your Twilio credentials and it provisions new numbers into your Twilio account, billed to you. You choose the countries, and each one can keep a pool of reusable pre-verified numbers. This covers provisioning, not the numbers your Twilio WhatsApp senders already use. Those still follow Step 1. This is an Enterprise feature, or a paid add-on on other plans. See Provide local numbers.

Feature map

Things Kapso adds:

What does not map

  • Messaging Services. No sender pools, sticky sender, or geomatch. You send from a specific phone_number_id.
  • TwiML. Auto-replies move into your webhook handler or a workflow.
  • Link shortening and click tracking.
  • Conversation tags. Organize in the inbox UI, not the API.

Cutover

Migrate one number at a time. A number’s WhatsApp registration and webhook routing move as a unit, so there is no gradual split per number. One thing needs no migration. Meta bills message charges against the WABA on either platform, per delivered template message, at category and market rates. See pricing.
Message history does not transfer. Twilio keeps it in its Messages resource. Export what you need before you close the account.

Troubleshooting

Node.js example

Need help