Onboarding Metadata
Use metadata when the API consumer needs structured context to identify the phone number
created by an onboarding link.
externalId is still supported for one simple identifier. metadata is for a JSON object with
multiple values, for example customer, branch, plan, CRM, or integration IDs.
Contract
Send metadata in POST /v1/onboarding-links:
curl -X POST https://api.example.com/v1/onboarding-links \
-H "Authorization: Bearer sk_org_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Store 01",
"externalId": "customer-123",
"metadata": {
"customerId": "customer-123",
"locationCode": "store-01",
"crmAccountId": "crm_789",
"plan": "premium"
},
"redirectUrl": "https://myapp.com/whatsapp/callback"
}'
Rules:
| Field | Type | Required | Notes |
|---|---|---|---|
| metadata | object | No | Must be a JSON object, not an array or string |
| externalId | string | No | Keep using this for a single routing identifier |
Recommended usage:
- Store stable identifiers that help your backend map the connected phone to your own records.
- Keep values JSON-serializable.
- Do not store API keys, tokens, webhook secrets, or credentials.
- Avoid sensitive personal data unless the integration genuinely needs it.
Propagation
When the end-user completes Meta Embedded Signup:
- The onboarding link keeps
metadata. - The created or linked phone receives the same
metadata. - Existing phone metadata is preserved if that phone already had metadata.
This metadata is stored locally by this API. It is not sent to Meta and it is not appended to the public signup redirect URL.
Where It Is Returned
The secured API returns metadata in these responses:
GET /v1/onboarding-linksGET /v1/onboarding-links/{onboardingLinkId}GET /v1/wabasGET /v1/wabas/{wabaId}/connectionGET /v1/phones/{phoneNumberId}
Example completed onboarding link:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Store 01",
"status": "completed",
"externalId": "customer-123",
"metadata": {
"customerId": "customer-123",
"locationCode": "store-01",
"crmAccountId": "crm_789",
"plan": "premium"
},
"phoneNumberId": "660e8400-e29b-41d4-a716-446655440001",
"phoneNumber": "+5491155551234",
"wabaId": "770e8400-e29b-41d4-a716-446655440002"
}
}
Example phone detail:
{
"data": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"phoneNumberId": "123456789012345",
"phoneNumber": "+5491155551234",
"metadata": {
"customerId": "customer-123",
"locationCode": "store-01",
"crmAccountId": "crm_789",
"plan": "premium"
},
"isRegistered": true
}
}
Verification Path
After creating a link and completing signup:
curl https://api.example.com/v1/onboarding-links/{onboardingLinkId} \
-H "Authorization: Bearer sk_org_..."
Confirm:
data.metadataequals the object sent during link creation.data.phoneNumberIdis present.
Then check the linked phone:
curl https://api.example.com/v1/phones/{phoneNumberId} \
-H "Authorization: Bearer sk_org_..."
Confirm:
data.metadataequals the onboarding link metadata.data.idequals thephoneNumberIdreturned by the onboarding link GET.