signInWithOtp and verifyOtp stay as they are.
Your app signs people in with Supabase Auth by phone. Supabase makes the code and checks it; Tawked delivers it. You point Supabase’s Send SMS hook at Tawked, and every code Supabase makes goes out as a Tawked Verify SMS: to Saudi mobile numbers, under Tawked’s sender ID, with the text naming your reviewed application. The product page, in English and Arabic, has the short version.
Your app’s code stays as it is:
Use the hook when your app already signs people in with Supabase Auth. If your own server starts and checks codes, use the Verify API instead; both can live side by side on one application.
Before you start
- A Tawked application with Tawked Verify. The fastest start is the Supabase sign-up, tawked.com/en/signup?product=verify&via=supabase: it makes the application with Verify and opens its Supabase page.
- A Supabase project with phone sign-in, and access to its Authentication settings.
- To create the connection: the owner, or an admin or developer whose access covers the whole application, since it makes keys.
Set it up
1
Create the connection in Tawked
In the console, open the application, then Integrations, then Supabase, and choose Create the connection. The page shows a Hook URL for this application alone and a Secret. The application needs Verify, and whoever manages the application’s API keys (the owner, or an admin or developer whose access covers the whole application) creates the connection and sees the Secret.
2
Add the hook in Supabase
In your Supabase project open Authentication, then Auth Hooks, choose Add hook, then Send SMS hook. Choose HTTPS, paste the Hook URL and the Secret, and save. If Supabase made a secret for you instead, paste that one into Tawked under Have a secret from Supabase?: either way, both sides must hold the same one.
3
Turn on phone sign-in
In Authentication › Sign In / Providers, turn on Phone. Then sign in to your app with your own phone. The Supabase page in Tawked updates by itself when the first request arrives and when the first code goes out.
https://tawked.com/webhooks/supabase/{connection}, and the Secret starts with v1,whsec_ followed by Base64. Treat the Secret like an API key: keep it in Supabase’s hook settings or your secret manager, never in your app’s code.
The local Supabase CLI
For a project run with the Supabase CLI, the same hook goes insupabase/config.toml:
TAWKED_SUPABASE_HOOK_SECRET=v1,whsec_...), then restart the local stack with supabase stop and supabase start.
Configure
On the application’s Integrations → Supabase page:Review and test mode
Every application is reviewed before its codes reach the public, and the hook follows the same rule as a test key:- In review: codes reach the phone the account owner verified at signup, and no other number. Each one carries the test stamp and counts toward the same 10 sends per application as any sandbox send. Any other number is refused with “is in review”.
- Approved: codes reach every Saudi mobile number.
- Rejected, suspended or archived: nothing is sent, and every request is refused.
Supabase checks the code, so Tawked never learns whether the person typed it. These codes are delivery only: the Verify API answers
404 not_found for them, they never expire into a verification.expired webhook, and the Verify log shows them as sent, with “Supabase checks the code”. Never read their state as the sign-in result: verifyOtp is the answer.What Supabase sends
Supabase calls the Hook URL with aPOST signed by Standard Webhooks: the headers webhook-id, webhook-timestamp and webhook-signature (v1, and a Base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, keyed by the Secret). Tawked refuses a signature it cannot match, and a timestamp more than five minutes away from its clock.
sms.phone, where the code goes (the new number on a phone change), oruser.phonewhensms.phoneis missing. Supabase writes numbers as digits with the country code and no+.sms.otp, the code, sent as it is: 4 to 10 digits.user.id, kept as the verification’s reference, so the Verify log finds the person the code was for.metadata.ip_address, the address of the person signing in, given to the per-IP cap of the protection guard.metadata.uuid, the request’s identity. Supabase retries with a newwebhook-idand the samemetadata.uuid, so a retried request is sent and charged once.
What Tawked answers
A code that went out is200 with an empty object:
200, because Supabase reads the reason only from a 200. The body carries the status Supabase gives your app and the message it shows:
«Your app» stands for your application’s English name.
Limits
- Saudi mobile numbers only (
+9665…). A Supabase project with numbers from other countries has to route those elsewhere itself: the hook has one address, and Tawked refuses every other number with422. - SMS only. The hook carries no channel, so a code always goes by SMS, even when your app asked Supabase for WhatsApp.
- Five seconds. Supabase waits five seconds for the hook’s answer. Tawked hands the SMS over for delivery within the call and gives the SMS gateway four seconds of it, so
{}means the code left Tawked. A send that cannot be handed over in time is refused with502and refunded. - Rate limits. The Verify caps apply to the hook’s codes: 5 codes per number per hour by default and, once the application is approved, the per-IP cap, the daily spend cap and the new-destination guard (see Reliability and limits). One connection takes up to 600 requests a minute; past that it answers
429withRetry-After. Supabase’s own SMS rate limits (Authentication › Rate Limits) apply before any request reaches Tawked.
Troubleshooting
"is in review": codes reach only one phone
"is in review": codes reach only one phone
Until the application is approved, codes reach the account owner’s verified phone only, stamped as a test. Sign in with that phone to try the flow; codes reach every Saudi number once the review approves the application, with nothing to change in Supabase.
"the account balance is too low"
"the account balance is too low"
Each code is paid from the account’s prepaid balance. Top up the wallet in the console; turn on the balance alert or auto top-up on the wallet’s Balance page so sign-ins never stop.
"Saudi mobile numbers only"
"Saudi mobile numbers only"
The number is not a Saudi mobile, or your app passed it with a leading zero after the country code (
+9660 5…). Pass numbers to signInWithOtp as +9665 followed by 8 digits.Nothing arrives and the Supabase page still waits
Nothing arrives and the Supabase page still waits
The request never reached Tawked. Check that the Send SMS hook is turned on, that its type is HTTPS, that the URL is the whole Hook URL, and that Phone is on in Sign In / Providers.
Disconnecting and your data
- Disconnect Supabase revokes the connection’s keys at once, so sign-in codes in your project stop until you connect again or turn the Send SMS hook off in Supabase. Codes already sent stay in the Verify log.
- Each code is a row of the Verify log: the number it went to, the Supabase user’s id as its reference, and its outcome. Tawked reads nothing else from your Supabase project: only what each request carries.
- The Secret is stored encrypted and shown only to whoever manages the application’s keys.