For the complete documentation index, see llms.txt. This page is also available as Markdown.

Pre-verified phone numbers

lightbulb-on

How pre-verification works

Pre-verification lets you verify phone numbers via API before your clients ever reach Embedded Signup. Instead of requiring clients to add a number and enter an OTP themselves during onboarding, you handle that step in advance — either by maintaining a pool of pre-verified numbers ready to be assigned, or by verifying a specific customer's number right before sending them to the ES flow.

Once a number is verified, you pass its ID to the onboarding flow. The client can then select and connect it without going through phone number verification at all. This works whether you are hosting your own Embedded Signup or using 360dialog's Integrated Onboarding.

Verification statuses

A number moves through the following statuses during its lifecycle:

Status
Meaning

NOT_VERIFIED

In the pool, ownership not yet proven.

VERIFIED

Ownership proven. Ready to be claimed during onboarding.

EXPIRED

The 90-day window closed. Must be re-verified before it can be used.

Numbers can be re-verified after 45 days to maintain continuous verified status. We recommend tracking verification dates and re-verifying before the window closes to avoid gaps.

Verifying numbers

This section covers the API endpoints for managing your pre-verified pool: adding numbers, requesting and verifying OTPs, listing the pool, and deleting numbers.

Process overview

1

Add the number

Register it with Meta and get back a preverified_phone_number_id

2

Request an OTP

Trigger an SMS or voice code to be sent to the number

3

Verify the OTP

Submit the code to prove ownership. The number becomes VERIFIED and a 90-day window opens

4

Pass the ID to onboarding

Include the preverified_phone_number_id when sending the client to your ES flow or Integrated Onboarding link

5

Client completes onboarding

They see the number pre-selected and skip verification entirely

6

Receive confirmation

A preverified_number_claimed webhook fires when the number is connected, telling you which channel it became

Base URLs

{partner_id} is your 360dialog partner ID (e.g. examplePA).

Authentication

Every request must include your Partner API key in the x-api-key request header.

Error format

Errors share a common envelope:

Field
Notes

360dialog_trace_id

Include this when contacting support — it identifies the request.

developer_message

Human-readable reason.

details

Present on validation errors; keyed by location (json, query, path) and then by field name.

A 401 is returned when the API key is missing or invalid.

Step 1 — Add a number to the pool

Please use this endpoint.

Registers a phone number with Meta and shares it with the partner's Meta business so it can later be claimed by a client.

Request body

Field
Type
Required
Notes

phone_number

string

yes

Digits only, no leading +. 6–20 characters, pattern ^\d+$.

Response — 201 Created

Field
Notes

preverified_phone_number_id

Meta's pre-verified phone number ID. Use it as {id} in subsequent calls.

country_code

ISO 3166-1 alpha-2 (lowercase), derived from the number. May be null if it can't be determined.

code_verification_status

Starts as NOT_VERIFIED.

Adding a number already in your pool returns the existing record (idempotent).

Error cases

Status
When

400

phone_number fails validation, or the partner has no Meta business ID configured (Partner business id is not configured for this partner).

404

The partner does not exist.

409

The number is already registered in a different pool.

502

The request to Meta's API failed.

Step 2 — Request an OTP

Please use this endpoint.

Triggers a Meta OTP to be sent to the number.

Request body

Field
Type
Required
Notes

code_method

string

yes

Delivery method. One of sms, voice.

language

string

yes

Locale for the OTP message, e.g. en_US.

Supported code_method values

Value
Delivery

sms

Code sent by SMS text message.

voice

Code delivered by an automated voice call.

language is a Meta locale code passed straight through to Meta — for example en_US, en_GB, de, es, fr, it, pt_BR, nl, id. Refer to Meta's list of supported languages for the full set. Choose a locale the recipient can read; voice calls read the code aloud in that language.

Response — 200 OK

Error cases

Status
When

400

Invalid code_method, or Meta rejected the request (e.g. invalid number for OTP).

404

No pre-verified number with this ID in the pool.

Step 3 — Verify the OTP

Please use this endpoint.

Submits the code received on the number. On success the number becomes VERIFIED and the 90-day window starts.

Request body

Field
Type
Required
Notes

code

string

yes

The OTP code received on the number, e.g. 123456.

Response — 200 OK

Error cases

Status
When

400

Meta rejected the code (e.g. Invalid verification code).

404

No pre-verified number with this ID in the pool.

List numbers

Please use this endpoint.

Returns the numbers in the partner's pool.

Query parameters

Param
Type
Filters?
Notes

code_verification_status

string

yes (exact)

One of NOT_VERIFIED, VERIFIED, EXPIRED.

phone_number

string

yes (exact)

Digits only, no leading +, pattern ^\d+$.

country_code

string

no

Ordering hint only — see below.

country_code (ISO 3166-1 alpha-2, lowercase) does not filter the result. Numbers whose country matches are returned first, all others follow. Use it to surface the most relevant numbers (e.g. de) at the top without hiding the rest of the pool.

Response — 200 OK

Error cases

Status
When

400

An invalid query value, e.g. code_verification_status outside the allowed set.

Delete a number

Please use this endpoint.

Deletes the number from Meta and removes it from the partner's pool.

Response — 200 OK

Error cases

Status
When

404

No pre-verified number with this ID in the pool.

502

The request to Meta's API failed.

Passing pre-verified numbers to onboarding

Once a number is VERIFIED, you need to make it available to your clients during their Embedded Signup session. How you do this depends on how you are delivering the onboarding flow.

Self-hosted Embedded Signup

If you host the ES flow yourself, you can surface pre-verified numbers in the signup form using pre-filled form data. Add a preVerifiedPhone object with an ids array to the setup object and assign the preverified_phone_number_id values of the numbers you want to make available:

Full example

Completing the connection

After the client finishes the ES session, Meta returns a phone number ID. You must pass this to 360dialog to complete the channel setup:

Pass the Meta Phone Number ID received from the ES session in this request. See the self-hosted Embedded Signup documentation for the full details on this step.

Pass the preverified_phone_number_id directly into your onboarding flow so the number is pre-selected when the client goes through the 360dialog-hosted signup.

Connect Button

Install the latest version of the Connect Button package:

Pass the ID via the preverified_phone_number_id query parameter:

If you're using a direct link instead of the Connect Button, append the query parameter to the onboarding URL ...?preverified_phone_number_id=<preverified_phone_number_id>

Webhook: preverified_number_claimed

When a client claims one of your pre-verified numbers during Embedded Signup, the number is removed from the pool and a channel is created for it. At that moment 360dialog sends a preverified_number_claimed event to your partner webhook so you can reconcile the claimed number with the channel it became.

When it fires

  • The number was in your partner pool (not the 360dialog-owned pool), and

  • a new channel was created for it during onboarding.

It fires once, on the onboarding that creates the channel — not on later re-syncs of an existing channel. Delivery only happens if you have a webhook URL configured for the partner.

Delivery

  • Method: POST to your configured partner webhook URL.

  • Headers: Content-Type: application/json.

  • Expected response: 2xx. Delivery is a single attempt — not retried on failure, so your endpoint should acknowledge quickly and process asynchronously.

Payload

Field
Notes

id

Unique event/delivery ID.

event

Always preverified_number_claimed.

data.preverified_phone_number_id

Matches the ID returned when you added the number to the pool.

data.id

The newly created channel ID.

data.setup_info.phone_number

The claimed phone number.

data.waba_account

The WABA the number was connected to (external_id is the Meta WABA ID).

data.client

The client that claimed the number.

Use data.preverified_phone_number_id to match the event back to the number you added to the pool, and data.id / data.waba_account to know which channel and WABA it became.

Last updated

Was this helpful?