One-time passcodes,
delivered on WhatsApp.

رمز التحقق على واتساب

Two API calls: one to send a code, one to check it. Your users get the message in the app they already have open, and you never touch a WhatsApp Business Account.

your server

POST /v1/verify/start

{ "to": "+966501234567" }

 

POST /v1/verify/check

{ "verification_id": "b9c1…", "code": "……" }

 

Enter the code from the message

Type it yourself, the code is on the phone

Zameel

Business account

402913 is your verification code.

For your security, do not share this code.

9:41

Meta fixes the wording of authentication templates.
The code is the only variable you supply.

Time to first message

The six weeks you get to skip.

Sending an OTP over WhatsApp yourself means becoming a WhatsApp business first. That is a real project with a queue at every stage. We already stood in all of them.

On your own

roughly six weeks

Business verificationBusiness verification, 5 to 15 days
App reviewApp review, 5 to 10 days
Template approval, 1 to 3 days
Number and display name, 1 to 2 days
Messaging tier warm-upMessaging tier warm-up, ongoing

With Zameel Authentication

this afternoon

Create an application, copy the key

Typical durations for a first-time applicant, not a guarantee. Business verification and app review are the two that most often run long, and neither has an appeal you can hurry.

Drop it in

Nothing to model, nothing to store.

No codes table, no expiry job, no attempt counter of your own. You hold one id between two requests and we hold everything else, including the part you would least want to get wrong.

  • The code is hashed the moment it is generated and never returned to you, in any mode.
  • Checking is atomic, so a race cannot spend more attempts than the policy allows.
  • Destination numbers are kept masked, so your log is not a phone book.
# 1. Send the code
curl https://api.zameel.co/api/v1/verify/start \
  -H "Authorization: Bearer $ZAMEEL_AUTH_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+966501234567" }'

# { "data": { "id": "b9c1…", "status": "pending" } }

# 2. Check what the user typed
curl https://api.zameel.co/api/v1/verify/check \
  -H "Authorization: Bearer $ZAMEEL_AUTH_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "verification_id": "b9c1…", "code": "402913" }'

# { "data": { "status": "verified", "verified": true } }

Built in, not bolted on

Protection against the attack nobody warns you about.

Verification endpoints get pumped. An attacker triggers thousands of sends to numbers they control, and the bill lands on whoever owns the sender. Every application starts with the controls that stop it.

500 requests from 12 numbers an attacker controls

The same flood, with and without the controls every application starts with.

Without protection

Delivered

0

Refused

0

Cost

$0.00

Every request becomes a delivered message, and every message is billed to whoever owns the sender.

Zameel Authentication

Delivered

0

Refused

0

Cost

$0.00

Each number is capped at 3 sends an hour, so the flood stops paying out after 36 messages.

Per-number limits

One destination can only be targeted a few times an hour and a few times a day. A scripted signup form cannot be turned into a message pump.

Country allowlist, default-deny

A new application sends nowhere until you enable the countries you actually operate in. The expensive destinations attackers prefer stay closed.

Prepaid balance

Spend cannot run away from you overnight. When the balance reaches zero, sending stops. A hard ceiling, not a surprise invoice.

Attempt lockout

Codes expire, are single-use, and lock after a set number of wrong guesses. Counting is atomic, so parallel requests cannot buy extra attempts.

Reach

Turn on the countries you sell to.

Enabling a destination is one toggle. Leaving it off is the safer default, and that is how every new application starts.

Saudi Arabia+966United Arab Emirates+971Kuwait+965Qatar+974Bahrain+973Oman+968Jordan+962Egypt+20Turkey+90United Kingdom+44United States / Canada+1India+91Pakistan+92Indonesia+62Saudi Arabia+966United Arab Emirates+971Kuwait+965Qatar+974Bahrain+973Oman+968Jordan+962Egypt+20Turkey+90United Kingdom+44United States / Canada+1India+91Pakistan+92Indonesia+62
Oman+968Jordan+962Egypt+20Turkey+90United Kingdom+44United States / Canada+1India+91Pakistan+92Indonesia+62Saudi Arabia+966United Arab Emirates+971Kuwait+965Qatar+974Bahrain+973Oman+968Jordan+962Egypt+20Turkey+90United Kingdom+44United States / Canada+1India+91Pakistan+92Indonesia+62Saudi Arabia+966United Arab Emirates+971Kuwait+965Qatar+974Bahrain+973

What it costs

Meta's rate, and nothing on top.

Cloud API hosting is free and the per-message rate is the same whoever you buy through. The difference is whether somebody adds a margin to it.

5,000

500100,000

Destination

Your monthly cost

$54

5,000 authentication messages to Saudi Arabia at $0.0107 each.

Direct, through Zameel$54
Through a typical reseller$84

$30 a month of that gap is reseller markup, not Meta.

Indicative only. Meta publishes authentication rates per country and revises them periodically, and messages to a country different from your sender's registration country bill at the higher authentication-international rate. Reseller markup uses the mid-point of the commonly published $0.003 to $0.010 band. Check the current rate card before you commit to a price.

Worth knowing

Where WhatsApp is the wrong channel.

The number needs WhatsApp

If a recipient has no WhatsApp account, the message cannot be delivered. In the GCC that is a small minority. In markets where WhatsApp is not dominant, plan an SMS path alongside it.

Primary device only

Meta delivers authentication messages to a user's primary phone, never to a linked desktop session. That is a security property rather than a limitation, but it is worth telling your users.

Send your first code in the next five minutes.

Create an application, copy the test key, and run the sample. Test keys never send a message and never cost anything.

Pricing

Simple, honest pricing

Prices shown in your local currency. Cancel any time.