Conversation API migration guide
A guide on how to migrate to Sinch's Conversation API
Onboarding
Migrating Active Numbers
If you are currently using Sinch LATAM WhatsApp API and desire to migrate to Sinch Conversation API + WhatsApp service, please contact your Account Manager and request the migration.
After the migration request is submitted, we will schedule the migration date. On the scheduled day, our team will handle the migration process automatically for you, which means that your active numbers will stop working on the Latam platform and start working exclusively on the Conversation API. It is very important that you prepare your backend and integration with us accordingly, and verify that everything is working as expected during and after the migration process.
Starting from Scratch
If you do not have any active numbers in Latam and want to start using the Native Conversation API from scratch, simply follow the official setup guide below:
Sending Your First Message
Now that you have completed the onboarding process, you can send your first message.
If you don’t want to add or migrate your own phone number to test Conversation API Platform, you can contact your Account Manager and he will provide a demo test number for you, following these steps:
You may create a new subproject in your Sinch Build Configuration, let’s say
ConvAPI Integration Check. Ask your account manager to help you create a subproject.Contact your account manager and ask them to get a Sinch demo number and have it assigned to
ConvAPI Integration Checksubproject. You’ll have a maximum of 30 days to use this demo number for testing / validation purposes.Create a new ConvAPI App under
ConvAPI Integration Checksubproject and assign this WA demo number to it.Do full WA testing using your backend systems and make sure that both outbound and inbound traffic is working fully as expected.
To send your first message of the WA testing, you can use one of these two ways:
Using Sinch Build Test Tool (https://dashboard.sinch.com/convapi/apps/{your-app}/test-message)
Directly Through Conversation API
Option 1 - Sinch Build Test Tool
After creating an app and having a number associated with it, you may go to your App Sinch Build Page - https://dashboard.sinch.com/convapi/apps/, select your app, and click Send Test Messages under the Test your setup section.
This is an easier way to test your environment, since we prepare the payload, authentication and URL automatically for you, so that you can send the request with one click, but it’s also a limited environment, since we will not route incoming webhooks to your URL in the test mode.
Option 2 - Directly Through Conversation API
Since we’re using a simple non-template payload for this example, you must first send a message from the destination_phone_number to the business, opening the WhatsApp Customer Service Window. If you don’t want to do that, you can use a template message and skip this step.
Use your key_id and key_secret to complete WhatsApp Migration guide from Latam to Native ConvAPI | Native Conversation API Authentication and add the Authentication Header to your request.
Native Conversation API Authentication
All authentication information needed is described in Authentication.
You can test sending messages with Basic Auth using your key_id and key_secret, but OAuth Token is highly recommended.
Sending a Simple Text Payload
The endpoint used to send messages depends on your environment, and can be one of the following:
Conversation API (US Production)
https://us.conversation.api.sinch.com/v1/projects/{project_id}/messages:send
Conversation API (EU Production)
https://eu.conversation.api.sinch.com/v1/projects/{project_id}/messages:send
Conversation API (BR Production)
https://br.conversation.api.sinch.com/v1/projects/{project_id}/messages:send
Check the Overview for a complete Postman Collection and our API documentation.
In this example, send the following payload to your Conversation API endpoint:
If you’ve completed the three steps, you should receive the message on your destination_phone_number.
Request Fields
Root payload
LATAM field
Sinch Conv API field
Notes
destinations
recipient
Destination list; each item becomes one message per recipient in Conv API.
message
message
Message payload content.
flowId
message_metadata.flowId
No dedicated field. You can set it in messageMetadata to receive it back in webhooks.
defaultExtraInfo
message_metadata.extraInfo
No dedicated field. You can set it in messageMetadata to receive it back in webhooks.
campaignAlias
message_metadata.campaignAlias
No dedicated field. You can set it in messageMetadata to receive it back in webhooks.
partnerId
message_metadata.partnerId
No dedicated field. You can set it in messageMetadata to receive it back in webhooks.
Destination
LATAM Destination field
Sinch Conv API field
Notes
correlationId
correlation_id
Per-recipient correlation.
destination
recipient.identified_by.channel_identities[0].identity
Recipient WhatsApp number/identity.
extraInfo
message_metadata.extraInfo
No dedicated field. You can set it in messageMetadata to receive it back in webhooks.
Message
LATAM Message field
Sinch Conv API field
Notes
messageText
message.text_message.text
Text message.
image
message.media_message
Image media payload.
audio
message.media_message
Audio media payload.
document
message.media_message
Document media payload.
location
message.location_message
Location payload.
contacts
message.contact_info_message
Contact payload (Conv processes one contact per message).
interactive
depends on interactiveMessageType
Interactive Payload.
template
message.template_message
Template Payload.
previewFirstUrl
channel_properties.WHATSAPP_PREVIEW_URL
First URL preview control.
Latam VS Conv API Requests
Text

Text Object
LATAM Text field
Sinch Conv API field
messageText
message.text_message.text
showFirstPreviewUrl
channel_properties.WHATSAPP_PREVIEW_URL
Latam Payload
Conv API Payload
Image

Image Object
LATAM Image field
Sinch Conv API field
Notes
type
-
No need to specify type.
caption
message.card_message.description
To use media with a caption (check example), you need to use Sinch’s card message.
url
message.media_message.url or message.card_message.media_message.url
Media URL.
data
-
Conv API does not allow base64 media content.
Latam Payload
Conv API Payload
Image With Caption

Image Object
LATAM Image field
Sinch Conv API field
Notes
type
-
No need to specify type.
caption
message.card_message.description
To use media with a caption (check example), you need to use Sinch’s card message.
url
message.card_message.media_message.url
Media URL.
data
-
Conv API does not allow base64 media content.
Latam Payload
Conv API Payload
Audio

Audio Object
LATAM Audio field
Sinch Conv API field
Notes
type
-
No need to specify type.
url
message.media_message.url
Media URL.
data
-
Conv API does not allow base64 media content.
Latam Payload
Conv API Payload
Document

Document Object
LATAM Document field
Sinch Conv API field
Notes
type
-
No need to specify type.
caption
message.card_message.description
To use media with a caption, you need to use Sinch’s card message.
url
message.media_message.url or message.card_message.media_message.url
Document URL.
data
-
Conv API does not allow base64 media content.
filename
message.media_message.filename_override or message.card_message.media_message.filename_override
Document Name.
Latam Payload
Conv API Payload
Contact

Contact Object
LATAM Contact field
Sinch Conv API field
addresses
message.contact_info_message.addresses
birthday
message.contact_info_message.birthday
emails
message.contact_info_message.emailAddresses
name
message.contact_info_message.name
org
message.contact_info_message.organization
phones
message.contact_info_message.phoneNumbers
urls
message.contact_info_message.urls
Contact’s Address
LATAM Contact Address field
Sinch Conv API field
street
message.contact_info_message.addresses[*].street
city
message.contact_info_message.addresses[*].city
state
message.contact_info_message.addresses[*].state
zip
message.contact_info_message.addresses[*].zip
country
message.contact_info_message.addresses[*].country
country_code
message.contact_info_message.addresses[*].countryCode
type
message.contact_info_message.addresses[*].type
Contact’s Email
LATAM Contact Email field
Sinch Conv API field
email
message.contact_info_message.email_addresses[*].emailAddress
type
message.contact_info_message.email_addresses[*].type
Contact’s Name
LATAM Contact Name field
Sinch Conv API field
first_name
message.contact_info_message.name.first_name
last_name
message.contact_info_message.name.last_name
middle_name
message.contact_info_message.name.middle_name
name_suffix
message.contact_info_message.name.suffix
name_prefix
message.contact_info_message.name.prefix
formatted_name
message.contact_info_message.name.full_name
Contact’s Org
LATAM Contact Org field
Sinch Conv API field
company
message.contact_info_message.organization.company
department
message.contact_info_message.organization.department
title
message.contact_info_message.organization.title
Contact’s Phone
LATAM Contact Phone field
Sinch Conv API field
Notes
phone
message.contact_info_message.phone_numbers[*].phone_number
Phone number.
type
message.contact_info_message.phone_numbers[*].type
Phone type.
wa_id
No dedicated direct field
Usually treated as auxiliary metadata.
Contact’s Url
LATAM Contact Url field
Sinch Conv API field
Notes
url
message.contact_info_message.urls[*].url
URL.
type
message.contact_info_message.urls[*].type
URL type.
Latam Payload
Conv API Payload
Location

Location Object
LATAM Location field
Sinch Conv API field
Notes
geopoint
message.location_message.coordinates
Geopoint.
address
message.location_message.label
Address
name
message.location_message.title
Name/Title.
Latam Payload
Conv API Payload
Interactive
Interactive Object
LATAM Interactive Type
Sinch Conv API field
Notes
interactive
message interactive output (varies by messageInteractiveType)
Interactive object.
messageInteractiveType = "LIST"
message.list_message
List action mapped to list_message.
messageInteractiveType = "REPLY_BUTTON"
message.card_message
Reply buttons mapped to card choices.
messageInteractiveType = "PRODUCT_LIST"
message.list_message
Product list mapped to ListMessage with ProductItem.
messageInteractiveType = "CTA_URL"
message.choice_message or message.card_message
Uses cardMessage only when header has media (IMAGE, VIDEO, DOCUMENT).
messageInteractiveType = "EXTENSION"
message.channel_specific_message.WHATSAPP (message_type = "FLOWS")
Flow payload serialized as channel-specific message.
messageInteractiveType = "ORDER"
message..channel_specific_message.WHATSAPP (messageType = "order_details")
Order payload serialized as channel-specific message.
Body, Header, Footer (Common Interactive Fields)
Latam Interactive field
Sinch Conv API field
Notes
interactive.body.text
message.list_message.title
For list and product_list.
interactive.body.text
message.card_message.title
For reply_button and CTA with media header.
interactive.body.text
message.choice_message.text_message.text
For CTA without media header.
interactive.body.text
message.channel_specific_message.WHATSAPP.body.text
For extension and order.
interactive.footer.text
message.list_message.description
For list; for product_list depends on multi/single product rule.
interactive.footer.text
message.card_message.description
For reply_button and CTA with media header; for product_list depends on multi/single product rule.
interactive.footer.text
message.choice_message.message_properties.whatsapp_footer
For CTA without media header.
interactive.footer.text
message.channel_specific_message.WHATSAPP.footer.text
For extension and order.
interactive.header.text
message.list_message.message_properties.whatsapp_header
For list.
interactive.header.text
message.card_message.message_properties.whatsapp_header
For reply_button.
interactive.header.image.url / video.url / document.url
message.card_message.media_message.url
For reply_button and CTA with media header.
interactive.header.<media>.caption
message.card_message.media_message.filename_override
Caption is mapped as filename override.
interactive.header.*
message.channel_specific_message.header
For extension and order, mapped as structured header (text, image, video, document).
Interactive List

Interactive
LATAM Interactive Type
Sinch Conv API field
interactive
message interactive output (varies by messageInteractiveType)
messageInteractiveType = "LIST"
message.list_message
Interactive’s ListAction
LATAM Interactive List Action field
Sinch Conv API field
Notes
interactive.listAction.button
message.list_message.message_properties.menu
Stored as message property, not a dedicated top-level list field.
interactive.listAction.sections[*]
message.list_message.sections[*]
Section array.
Interactive’s ListSection
LATAM Interactive List Action Sections Field
Sinch Conv API field
Notes
interactive.listAction.sections[*].title
message.list_message.sections[*].title
Optional section title.
interactive.listAction.sections[*].rows[*]
message.list_message.sections[*].items[*]
Rows become list items with choice.
Interactive’s ListRow
LATAM Interactive List Row Field
Sinch Conv API field
Notes
interactive.listAction.sections[*].rows[*].title
message.list_message.sections[*].items[*].choice.title
Required.
interactive.listAction.sections[*].rows[*].identifier
message.list_message.sections[*].items[*].choice.postback_data
Required.
interactive.listAction.sections[*].rows[*].description
message.list_message.sections[*].items[*].choice.description
Optional.
Latam Payload
Conv API Payload
Interactive Product List

Fields Comparison
Interactive
LATAM Interactive Type
Sinch Conv API field
interactive
message interactive output (varies by messageInteractiveType)
messageInteractiveType = "PRODUCT_LIST"
message.list_message
Interactive’s ProductListAction
Latam Interactive Product List field
Sinch Conv API field
Notes
interactive.productListAction.catalogId
message.list_message.message_properties.catalog_id
Required.
interactive.productListAction.sections[*]
message.list_message.sections[*]
Multi-product path.
interactive.productListAction.productRetailerId
message.list_message.sections[0].items[0].product.id
Single-product fallback when sections is null.
(not in Latam)
message.list_message.sections[*].items[*].product.marketplace
Marketplace.
Interactive’s ProductListSection
Latam Interactive Product List Section field
Sinch Conv API field
Notes
interactive.productListAction.sections[*].title
message.list_message.sections[*].title
Optional.
interactive.productListAction.sections[*].productItems[*]
message.list_message.sections[*].items[*]
Product array.
Interactive’s ProductListItem
Latam Interactive Product List Item field
Sinch Conv API field
Notes
interactive.productListAction.sections[*].productItems[*].productRetailerId
message.list_message.sections[*].items[*].product.id
Required.
multi/single product rule
Condition
Sinch Conv API field
Latam Field
Multi Product List (more than one product across sections)
message.list_message.description
interactive.header.text
Single Product List
message.list_message.description
interactive.footer.text.
Latam Payload
Conv API Payload
Interactive Reply Button

Interactive
LATAM Interactive Type
Sinch Conv API field
interactive
message interactive output (varies by messageInteractiveType)
messageInteractiveType = "REPLY_BUTTON"
message.choice_message
Interactive’s ReplyButtonAction
Latam Interactive Reply Button Action field
Sinch Conv API field
Notes
interactive.replyButtonAction.buttons[*].reply.title
message.choice_message.choices[*].text_message.text
Button Title.
interactive.replyButtonAction.buttons[*].reply.payload
message.choice_message.choices[*].postback_data
Button Payload.
Latam Payload
Conv API Payload
Template
1) Template (base structure)
Latam Template field
Sinch Conv API field
Notes
template
message.template_message
Output type is template_message.
template.elementName
message.template_message.channel_template.WHATSAPP.template_id
Required .
template.languageCode
message.template_message.channel_template.WHATSAPP.language_code
Required .
template.*params
message.template_message.channel_template.WHATSAPP.parameters
Template parameters.
2) Body parameters
Body parameters are indexed from 1 in Sinch’s parameters (body[1], body[2], ...).
Latam Template field
Sinch Conv API field
Notes
template.bodyParameters[index]
parameters["body[index+1]text"]
1-based index (body[1]text, body[2]text, ...).
3) Header
Headers are indexed from 1 in Sinch’s parameters (header[1], header[2], ...).
3.1) Header text
Latam Template field
Sinch Conv API field
Notes
template.header.title
parameters["header[1]text"]
Used first when present.
3.2) Header media
Latam Template Header field
Sinch Conv API field
Notes
template.header.document.url
parameters["header[1]document.link"]
Required if document header selected.
template.header.document.caption
parameters["header[1]document.filename"]
Only when caption is not blank.
template.header.image.url
parameters["header[1]image.link"]
Required if image header selected.
template.header.image.caption
parameters["body[1]text"]
Caption is redirected to body parameter.
template.header.video.url
parameters["header[1]video.link"]
Required if video header selected.
template.header.video.caption
parameters["body[1]text"]
Caption is redirected to body parameter.
3.3) Header location
Latam Template Header Location field
Sinch Conv API field
Notes
template.header.location.geoPoint latitude
parameters["header[1]location.latitude"]
Latitude.
template.header.location.geoPoint longitude
parameters["header[1]location.longitude"]
Longitude.
template.header.location.name
parameters["header[1]location.name"]
Optional.
template.header.location.address
parameters["header[1]location.address"]
Optional.
3.4) Header parameters array
Latam Template Header Parameters field
Sinch Conv API field
Notes
template.header.parameters[index]
parameters["header[index+1]text"]
1-based index for each text entry.
4) Buttons
Buttons are indexed from 0 in Sinch’s parameters (button[0], button[1], ...).
4.1) URL and CALL
Latam Template Buttons field
Sinch Conv API field
Notes
template.buttons[index].type = URL + url
parameters["button[index]url[1]text"]
Direct mapping.
template.buttons[index].type = CALL + url
parameters["button[index]url[1]text"]
Same key path as URL type (value can be tel:).
4.2) QUICK_REPLY
Latam Template Buttons field
Sinch Conv API field
Notes
template.buttons[index].replyPayload
parameters["button[index]quick_reply[1]payload"]
Required for quick reply buttons.
4.3) FLOW
Latam Template Buttons field
Sinch Conv API field
Notes
template.buttons[index].flowDetails.type
parameters["button[index]flow[1]action.type"]
Added only when non-null flowDetails.
template.buttons[index].flowDetails.action.flowToken
parameters["button[index]flow[1]action.token"]
Optional value.
template.buttons[index].flowDetails.action.flowActionData
parameters["button[index]flow[1]action.data"]
Optional value.
template.buttons[index].flowDetails = null
(no parameters)
Button is skipped for FLOW parameter mapping.
4.4) ORDER_DETAILS
Latam Template Buttons field
Sinch Conv API field
Notes
template.buttons[index].orderDetails.paymentType
parameters["button[index]order_details[1]action.type"]
Optional.
template.buttons[index].orderDetails.referenceId
parameters["button[index]order_details[1]action.reference_id"]
Optional.
template.buttons[index].orderDetails.type
parameters["button[index]order_details[1]action.type_of_goods"]
Optional.
template.buttons[index].orderDetails.totalAmount.value
parameters["button[index]order_details[1]action.total_amount_value"]
Optional.
4.4.1) ORDER_DETAILS / order
Latam Template Buttons field
Sinch Conv API field
Notes
...order.subtotal.value
...action.order.subtotal_value
Optional.
...order.expiration.timestamp
...action.order.expiration_time
Optional.
...order.expiration.description
...action.order.expiration_description
Optional.
...order.tax.value
...action.order.tax_value
Optional.
...order.tax.description
...action.order.tax_description
Optional.
...order.catalogId
...action.order.catalog_id
Optional.
...order.shipping.value
...action.order.shipping_value
Optional.
...order.shipping.description
...action.order.shipping_description
Optional.
...order.discount.value
...action.order.discount_value
Optional.
...order.discount.description
...action.order.discount_description
Optional.
...order.discount.discountProgramName
...action.order.discount_program_name
Optional.
4.4.2) ORDER_DETAILS / items
Latam Template Buttons field
Sinch Conv API field
Notes
...order.items[itemIndex].retailerId
...action.order.items[itemIndex+1]retailer_id
1-based item index in key.
...order.items[itemIndex].name
...action.order.items[itemIndex+1]name
1-based item index in key.
...order.items[itemIndex].amount.value
...action.order.items[itemIndex+1]amount_value
1-based item index in key.
...order.items[itemIndex].quantity
...action.order.items[itemIndex+1]quantity
1-based item index in key.
...order.items[itemIndex].saleAmount.value
...action.order.items[itemIndex+1]sale_amount_value
1-based item index in key.
4.4.3) ORDER_DETAILS / payment settings
Latam Template Buttons field
Sinch Conv API field
Notes
...order.paymentSettings[p].orderPaymentPixSettings.*
...action.order.payment_settings[p+1].type = "pix" + pix fields
Type and fields: pix_code, pix_merchant_name, pix_key, pix_key_type.
...order.paymentSettings[p].orderPaymentBoletoSettings.*
...action.order.payment_settings[p+1].type = "boleto" + boleto fields
Field: boleto_digitable_line.
...order.paymentSettings[p].orderPaymentLinkSettings.*
...action.order.payment_settings[p+1].type = "payment_link" + link fields
Field: payment_link_uri.
5) Legacy HSM
Latam field
Sinch Conv API field
Notes
type = "hsm"
message.template_message
HSM is converted to the same template_message output type.
hsm.elementName
template_message.channel_template.WHATSAPP.template_id
Required.
hsm.languageCode
template_message.channel_template.WHATSAPP.language_code
Required.
hsm.parameters[index]
parameters["body[index+1]text"]
Only body parameters are mapped.
Template With No Parameters Example

Latam Payload
Conv API Payload
Template With Buttons Example

Latam Payload
Conv API Payload
Latam VS Conv API Request Responses
Success
Latam
Conv API
Error
Latam
Conv API
Latam VS Conv API Webhooks
Webhook Configuration
In the Sinch Conversation API, webhook URLs are configured at the Conversation API App level. Each Conversation API App is associated with a single business phone number. This means you can configure different webhook URLs for different business phone numbers. However, unlike the Latam Platform, there is no concept of subaccounts. As a result, it is not possible to route webhooks from the same business phone number to different webhook URLs based on account-level configurations.
To configure webhooks for a specific App, access the Apps Section on Sinch Build and open the desired App. In the Webhooks section, you can add and manage webhook configurations as described in the following documentation:
Fields Comparison
1) Webhook Types
Latam Webhook
Conv API Webhook
Notes
sent success status webhook
QUEUED_ON_CHANNEL status webhook
sent success from Latam is equivalent to
message_delivery_report.status = QUEUED_ON_CHANNEL in Conv API
delivered success status webhook
DELIVERED status webhook
delivered success from Latam is equivalent to
message_delivery_report.status = DELIVERED in Conv API
read status webhook
READ status webhook
read from Latam is equivalent to
message_delivery_report.status = READ in Conv API
failed status webhook
FAILED status webhook
failed from Latam is equivalent to
message_delivery_report.status = FAILED in Conv API
MO webhook
MO webhook
message.direction = TO_APP contactMessage webhook in Sinch.
2) Common wrapper fields (all Latam callbacks)
Latam field
Conv API field
Notes
total
-
Always single webhook in Conv API.
clientInfo.customerId
-
similar to project_id in Sinch.
clientInfo.subAccountId
-
similar to app_id in Sinch.
clientInfo.userId
-
No dedicated direct field.
data[*].campaignAlias
If
message_metadata
For status: message_delivery_report.metadata;
data[*].flowId
Callback metadata JSON
Same metadata source rule as above.
data[*].extraInfo
Callback metadata JSON
Same metadata source rule as above.
data[*].correlationId
correlationId
Optional.
data[*].origin
channel_metadata.whatsapp.sender_phone_number
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
data[*].userProfile.whatsAppId
channel_identity.identity
channelIdentity always filled in Sinch webhooks.
data[*].userProfile.name
channel_metadata.whatsapp.user_profile.display_name
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
data[*].userProfile.username
channel_metadata.whatsapp.userProfile.username
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
data[*].userProfile.countryCode
channel_metadata.whatsapp.user_profile.country_code
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
data[*].userProfile.phoneNumber
channel_metadata.whatsapp.user_profile.phone_number
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
data[*].userProfile.userId
channel_metadata.whatsapp.userProfile.userId
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
data[*].userProfile.parentUserId
channel_metadata.whatsapp.user_profile.parent_user_id
Optional.
channel_metadata not present on QUEUED_ON_CHANNEL status.
3) Status update callback (Latam)
3.1) Base status fields
Latam field
Conv API field
Notes
data[*].id
message_delivery_report.messageId
Converted from ULID to UUID format before output.
data[*].destination
message_delivery_report.channelIdentity.identity
Recipient identity.
data[*].origin
channel_metadata.whatsapp.senderPhoneNumber
Fallback lookup may be used when missing.
data[*].type
-
No dedicated direct field.
data[*].updatedDate
event_time
In Sinch there’s no concept of updated webhook times, we treat each one independently of each other.
data[*].updatedAt
event_time
In Sinch there’s no concept of updated webhook times, we treat each one independently of each other.
3.2) Delivery/sent/read flags and timestamps
Latam field
Conv API source
Notes
data[*].sentStatus
message_delivery_report.status (+ reason.code for FAILED)
QUEUED/DELIVERED/READ -> SENT_SUCCESS; FAILED -> fromConvStatus.
data[*].sentStatusCode
-
No dedicated direct field.
data[*].sent
-
Equivalent to message_delivery_report.status=SENT being triggered.
data[*].deliveredStatus
-
No dedicated direct field.
data[*].deliveredStatusCode
-
No dedicated direct field.
data[*].delivered
-
Equivalent to message_delivery_report.status=DELIVERED being triggered.
data[*].read
-
Equivalent to message_delivery_report.status=READ being triggered.
data[*].sentDate
message_delivery_report.status=SENT event_time
In Conv API it is only present in SENT status.
data[*].sentAt
message_delivery_report.status=SENT event_time
In Conv API it is only present in SENT status.
data[*].deliveredDate
message_delivery_report.status=DELIVERED event_time
In Conv API it is only present in DELIVERED status.
data[*].deliveredAt
message_delivery_report.status=DELIVERED event_time
In Conv API it is only present in DELIVERED status.
data[*].readDate
message_delivery_report.status=READ event_time
In Conv API it is only present in READ status.
data[*].readAt
message_delivery_report.status=READ event_time
In Conv API it is only present in READ status.
4) MO callback (message sent by end user)
4.1) Base MO fields
Latam field
Conv API field
Notes
data[*].id
-
No dedicated direct field.
data[*].source
message.channel_identity.identity
End-user source identity.
data[*].origin
channel_metadata.whatsapp.sender_phone_number
Business phone number.
data[*].messageId
message_delivery_report.message_id
Optional link to original MT message.
data[*].receivedDate
eventTime
Time of the event.
data[*].receivedAt
eventTime
Time of the event.
data[*].mtSentAt
-
No dedicated direct field.
5) MO message payload mapping by message type
5.1) Text MO
Latam field
Conv API field
Latam field
Conv API field
data[*].message.type = "TEXT"
Infered by contact_message subtype = text_message.
data[*].message.messageText
message.contact_message.text_message.text
5.2) Media MO (image/video/audio/document/sticker)
Latam field
Conv API field
Notes
data[*].message.type
message.contact_message.media_message
Infered by contact_message subtype = media_message.
data[*].message.mediaUrl
message.contact_message.media_message.url
Media strategy.
data[*].message.mimeType
-
No dedicated direct field.
5.3) Media-card MO
Latam field
Conv API field
data[*].message.type
Infered by contact_message subtype = media_message.
data[*].message.mediaUrl
message.contact_message.media_card_message.url
data[*].message.mimeType
-
data[*].message.caption
message.contact_message.media_card_message.caption
5.4) Location MO
Latam field
Conv API field
data[*].message.type = "LOCATION"
Infered by contact_message subtype = media_message.
data[*].message.location.geoPoint
message.contact_message.location_message.coordinates as "lat,long"
data[*].message.location.address
message.contact_message.location_message.label
data[*].message.location.name
message.contact_message.location_message.title
5.4) Location MO
Latam field
Conv API field
data[*].message.type = "LOCATION"
Infered by contact_message subtype = mediaMessage.
data[*].message.location.geoPoint
message.contactMessage.locationMessage.coordinates as "lat,long"
data[*].message.location.address
message.contactMessage.locationMessage.label
data[*].message.location.name
message.contactMessage.locationMessage.title
Check WhatsApp Message Support | Conversation API | Sinch and WhatsApp Message Support | Conversation API | Sinch for the complete Conv API Documentation.
Failed Status Webhook Errors
Native Conversation API
Error Fields in Conv API
Based on the Meta’s error code (check Developer Platform) or in our WhatsApp Internal Processing, we may encounter failures which will trigger the failed status webhook.
When that happens, we will trigger a message_delivery_report status webhook with the following failure object:
Reason Object
Reason Field
Description
code
Internal Conv API Error Code.
description
Error Description. Will be Meta's error message in case of Meta Errors.
subCode
For WhatsApp, always "UNSPECIFIED_SUB_CODE"
channelCode
Meta Error Code, if applicable.
FAILED Status Webhook Payload Example
You may use the table below to see all possible code and channel_code values that can be returned inside the reason obejct:
Possible Error Values
Error
ReasonCode
Channel Code
FALLBACK_ERROR
INTERNAL_ERROR
-1
AUTH_EXCEPTION
CHANNEL_BAD_CONFIGURATION
0
API_UNKNOWN
CHANNEL_FAILURE
1
API_SERVICE
CHANNEL_FAILURE
2
API_METHOD
CHANNEL_REJECT
3
API_TOO_MANY_CALLS
RATE_LIMITED
4
API_PERMISSION_DENIED
CHANNEL_REJECT
10
INVALID_PARAMETER
BAD_REQUEST
100
ACCESS_TOKEN_EXPIRED
CHANNEL_REJECT
190
API_PERMISSION_NOT_GRANTED
CHANNEL_REJECT
200-299
TEMPORARILY_BLOCKED_POLICY_VIOLATION
CHANNEL_FAILURE
368
DUPLICATED_POST
CHANNEL_REJECT
506
RATE_LIMIT_ISSUE
RATE_LIMITED
80007
MEDIA_DOWNLOAD_ERROR
MEDIA_NOT_REACHABLE
131052
MEDIA_UPLOAD_ERROR
BAD_REQUEST
131053
PAYMENT_ISSUE
CHANNEL_REJECT
131042
MESSAGE_EXPIRED
CHANNEL_REJECT
131043
USER_NUMBER_PART_OF_EXPERIMENT
RECIPIENT_NOT_REACHABLE
130472
RATE_LIMIT_HIT
RATE_LIMITED
130429
UNSIGNED_CERTIFICATE
CHANNEL_REJECT
131045
SERVICE_OVERLOADED
CHANNEL_FAILURE
131016
RE_ENGAGEMENT_MESSAGE
OUTSIDE_ALLOWED_SENDING_WINDOW
131047
SPAM_RATE_LIMIT
DELIVERY_REJECTED_DUE_TO_POLICY
131048
META_CHOSE_NOT_TO_DELIVER
CHANNEL_FAILURE
131049
GENERIC_ERROR
CHANNEL_FAILURE
131000
MESSAGE_TOO_LONG
BAD_REQUEST
131001
INVALID_RECIPIENT_TYPE
BAD_REQUEST
131002
ACCESS_DENIED
CHANNEL_REJECT
131005
RESOURCE_NOT_FOUND
BAD_REQUEST
131006
REQUIRED_PARAM_MISSING
BAD_REQUEST
131008
PARAMETER_VALUE_NOT_VALID
BAD_REQUEST
33, 131009
BAD_USER
RECIPIENT_INVALID_CHANNEL_IDENTITY
131021
MESSAGE_UNDELIVERABLE
RECIPIENT_NOT_REACHABLE
131026
SENDER_ACCOUNT_LOCKED
CHANNEL_REJECT
131031
UNSUPPORTED_MESSAGE_TYPE
BAD_REQUEST
131051
METHOD_NOT_ALLOWED
CHANNEL_REJECT
131055
PAIR_RATE_LIMIT_HIT
RATE_LIMITED
131056
ACCOUNT_MAINTENANCE
CHANNEL_FAILURE
131057
TEMPLATE_PARAM_COUNT_MISMATCH
BAD_REQUEST
132000
TEMPLATE_DOES_NOT_EXIST
TEMPLATE_NON_EXISTING_LANGUAGE_OR_VERSION
132001
TEMPLATE_TEXT_TOO_LONG
BAD_REQUEST
132005
TEMPLATE_FORMAT_POLICY_VIOLATED
BAD_REQUEST
132007
TEMPLATE_PARAMETER_FORMAT_MISMATCH
BAD_REQUEST
132012
TEMPLATE_PAUSED
CHANNEL_REJECT
132015
TEMPLATE_DISABLED
CHANNEL_REJECT
132016
FLOW_BLOCKED
CHANNEL_REJECT
132068
FLOW_THROTTLED
CHANNEL_REJECT
132069
DELETE_INCOMPLETE
INTERNAL_ERROR
133000
DECRYPTION_ERROR
CHANNEL_FAILURE
133001
BACKUP_BLOB_DECRYPTION_ERROR
CHANNEL_FAILURE
133002
RECOVERY_TOKEN_DECRYPTION_ERROR
CHANNEL_FAILURE
133003
SERVER_TEMPORARILY_UNAVAILABLE
CHANNEL_FAILURE
133004
SECURITY_PIN_MISMATCH
CHANNEL_REJECT
133005
PHONE_NUMBER_REVERIFICATION_NEEDED
CHANNEL_REJECT
133006
ACCOUNT_BLOCKED
CHANNEL_REJECT
133007
TOO_MANY_PIN_GUESSES
CHANNEL_REJECT
133008
PIN_GUESSED_TOO_FAST
CHANNEL_REJECT
133009
PHONE_NUMBER_NOT_REGISTERED
CHANNEL_REJECT
133010
GENERIC_USER_ERROR
CHANNEL_REJECT
135000
Comparing to Latam Errors
In Latam, we have the following errors: WhatsApp API | Sinch | Latam Messaging Documentation
Since there’s no direct mapping between Latam ↔︎ Conv API error codes, in case you need to identify and handle a specific error, you may check the Channel Code Reason in the table above to identify and treat it accordingly.
Other Statuses Webhooks Examples
SENT STATUS
LATAM
CONV API
DELIVERED STATUS
LATAM
CONV API
READ STATUS
LATAM
CONV API
Check WhatsApp Message Support | Conversation API | Sinch for more information
MO Webhook Example
Latam
Conv API
Check WhatsApp Message Support | Conversation API | Sinch for more information.
Managing Templates
You can find the complete WhatsApp template documentation here:
Templates can be created and managed either:
Directly through the Sinch Build Dashboard - https://dashboard.sinch.com/whatsapp/message-templates
Programmatically through the Provisioning API - WhatsApp Templates
The migration should not impact your existing templates. We will synchronize all templates from Latam, making them ready to use in your new Native Conversation API environment once the migration is complete.
Opt Out
There is an important behavioral difference between the legacy Latam Platform and the Conversation API regarding opt-out handling.
In the Conversation API, when a user is identified as opted out and Consent Management is enabled, Sinch blocks all outgoing MT (mobile-terminated) messages for that identity, regardless of the message type. This includes marketing, utility, authentication, service, templated, and non-templated messages.
In contrast, the legacy Latam Platform only blocked marketing templates after an opt-out event. Non-templated messages and authentication/service templates could still be sent to the user even after they opted out.
This means the Conversation API provides a stricter and more centralized consent enforcement model, helping ensure compliance across channels and message categories.
All Conversation API opt-out and consent management features are available in the official Sinch documentation:
Consent Management | Sinch - Detailed Documentation
Consents - Consent API
To use Consent Management, the feature must first be enabled in the Sinch Build Dashboard.
Through the Consent API, you can:
Check whether an identity is opted out (using Get audit records from consent lists endpoint)
Retrieve identities from a consent list (using Get identities from consent list endpoint)
Main Differences from Latam
Migrating from the legacy Latam platform to the Sinch Conversation API brings architectural changes, including new limitations to be aware of and powerful new capabilities to scale your business.
Unsupported Features in Conversation API
Base64 Media Content: In the legacy Latam platform, you could send media by embedding base64-encoded data directly in the payload. The Sinch Conversation API does not support base64 media. All media (images, audio, documents, and videos) must be hosted and sent using publicly accessible URLs.
MM2 Portal Reports: The traditional reporting extraction via the Wavy MM2 platform is no longer available. Reporting, delivery receipts, and webhooks are now handled exclusively through the Sinch Conversation API delivery reports and the modern Sinch Customer Dashboard.
Marketing Templates Only Opt Out: Unlike the legacy Latam Platform, which only blocked marketing templates after an opt-out event, the Sinch Conversation API blocks all outbound message types for opted-out users.
Exclusive Conversation API Features
Continuous API Maintenance: The Conversation API has a dedicated team continuously improving the platform, adding new capabilities, and ensuring support for the latest Meta features and updates as they are released.
Direct Send API: Start conversations with users without needing to create pre-approved templates.
True Omnichannel Routing:The Conversation API provides a single, unified REST interface. You build your integration once, and you can reach your customers across any supported channel (WhatsApp, SMS, RCS, Instagram, Facebook Messenger, Apple Messages for Business, Viber, etc.) using the exact same API structure.
Last updated
Was this helpful?