WhatsApp API

WhatsApp API

Technical Documentation: WhatsApp API

WhatsApp API

This documentation provides information on how your application can send WhatsApp messages via API using the Wavy Messaging platform.

Here you will also find information on Webhooks, which are HTTP call returns set by the user that are triggered by specific events. Whenever a trigger event occurs, Wavy’s API will collect the data and immediately send a notification (HTTP request) to the URL chosen by our customer, updating the status of messages sent or letting you know when you receive a message.

Wavy Messaging’s API allows you to send single or bulk messages.

The API has REST integration, using HTTP protocol with TLS, supporting the POST method with parameters sent in JSON format.

Prerequisites

  1. To use Wavy Messaging’s API, first you need to have an active account on the Wavy Messaging platform. Refer to our documentation on Account & Settings for more information on how to follow this procedure.

  2. You must also have a valid username and token associated with this account. Learn how to create your username in our Adding Users guide.

  3. With the above credentials, you can already start using Wavy Messaging’s API.

Connection Details

Hostname

api-messaging.wavy.global

Port

443 (https)

Protocol

HTTPS (TLS encryption)

Authentication

username + token

Encoding

UTF-8

Making Calls to Wavy Messaging’s API

To make your first calls, we recommend using the “Postman” application with requests in JSON format instead of starting out already writing code in other languages.

Note: In order to send test messages, you need to have an approved message template in your WhatsApp Business account. Refer to our documentation on Creating WhatsApp Message Templates to create your first templates.

If you do not yet have any approved message templates, you can still send test messages as long as the recipient interacts with the source number. This way, a customer service window will be activated. It allows you to send any type of message within a 24-hour window. If your message arrives, it means your request to Wavy Messaging’s API was successful. If not, check your Webhook for notifications that could indicate any issues.

Messages:

Calls to Wavy Messaging’s API are sent to https://api-messaging.wavy.global/v1/whatsapp/send in POST format regardless of message type, but the content of the JSON message’s body varies for each type of message.

The authentication fields in the header will also follow the same format regardless of message type:

POST /v1/whatsapp/send HTTP/1.1 Host: api-messaging.movile.com UserName: user_name AuthenticationToken: aaaaaa-bbbbbbbbbbbbbXXXXX12 Content-Type: application/json

Sending a Template

Destinations

Name

Required

Description

destinations

Yes

Details on sent and destination identifiers

message

Yes

Details on the MESSAGE object that will be sent

Destination

Name

Required

Description

correlationId

No

Id set by the customer that will be returned in the message status (callback). You can use this id to track sent messages in a customized manner.

destination

Yes

Phone number that will receive the message (country code (55 for Brazil) and area code are required). Examples: 5519900001111, +5519900001111, +55(19) 900001111.

Message

Name

Required

Description

ttl

No

Time to live in days. It sets the maximum number of days in which the message should be delivered. Valid from 1 to 30. Default value is 7 if not set.

template

Yes

Details on the TEMPLATE object that will be sent

Template

Name

Required

Description

namespace

Yes

ID of the namespace that will be used. NOTE: The namespace and element_name parameters must match the Business Manager with which the source number is associated, otherwise the message will fail when sending.

elementName

Yes

Name of the registered and approved template.

header

Yes, when the Template has parameters in the header

Header objects with their parameters

languageCode

Yes

Name of the registered and approved template.

Name

Required

Description

title

Optional

Title must have no more than 60 characters

element

Yes

Options:

text (default),

image,

audio,

document,

hsm,

video.

Element

Name

Required

Description

url

Yes

Media URL. Use only with HTTP/HTTPS URLs.

type

Yes

Type of media (JPEG, MP3, PDF, etc.)

caption

Yes

Name of media

Webhooks

Webhooks (or callbacks) are HTTP call returns set by the user that are triggered by specific events. Whenever a trigger event occurs, Wavy’s API will collect the data and immediately send a notification (HTTP request) to the URL chosen by the customer updating the status of messages sent or letting you know when you receive a message.

When your customer sends you a message, Wavy Messaging’s API will send a POST HTTP request notification to the Webhook’s URL with the details.

It is important that your Webhook returns a 200 OK HTTPS response to notifications (within 200 ms or asynchronously). Otherwise, Wavy Messaging’s API will consider this notification to have failed and will try again after some delay.

Important: The URL where you will receive Webhooks must be set up by our support team.

General Format of a Webhook

Name

Object Content

messages

Incoming message notifications

statuses

Message status updates

Status

Status

Description

WhatsApp Equivalent for Mobile Devices

SENT_SUCCESS

Message received by WhatsApp’s server

One check mark

DELIVERED_SUCCESS

Message delivered to the recipient

Two check marks

READ_SUCCESS

Message read by the recipient

Two blue check marks

Errors

HTTP Code

Description

2xx

Success

200

Success (OK)

201

Successfully Created (For POST requests)

302

Found

4xx

Client Errors

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

405

Method Not Allowed

412

Precondition Failed

420

Message is Rate Limited

429

Too Many Requests

5xx

Server Errors

500

Internal Server Error

504

Timeout

Other Statuses

Sent Code

Delivery Code

Status

Meaning

102

CARRIER COMMUNICATION ERROR

Error in uploading media to WhatsApp

103

REJECTED_BY_CARRIER

A databank error has occurred

2

101

EXPIRED

Message expired

2

104

NOT_DELIVERED

Potential Causes:

Limit reached -too many attempts to send messages, or failure to send message because the destination phone number is part of an experiment, or the template structure does not exist, or failure to send message because the destination number is outside the 24h service window to receive messages freely, or an error occurred when uploading media (unknown error),

or failure to send message because your account is ineligible on Facebook Business Manager,

or there was a temporary upload failure. Please try again later.

202

INVALID_DESTINATION_NUMBER

Invalid WhatsApp contact

204

DESTINATION_BLOCKED_BY_OPTOUT

Destination blocked by Opt-Out

206

INVALID_MESSAGE_LENGTH

Message is too long

207

INVALID_MESSAGE_TEXT

Invalid parameter value

209

INVALID_CONTENT

Invalid type of UNKNOWN message

210

INVALID_SESSION

Session or service window is not open and no fallback Template is set up

311

INTERNAL_ERROR

Unable to verify WhatsApp API contacts

Messages (MO)

When a customer sends you a message, Wavy Messaging’s API will send a POST HTTP request to the Webhook’s URL with the details.

It is important that your Webhook returns a 200 OK HTTPS response to notifications (within 200 ms or asynchronously). Otherwise, Wavy Messaging’s API will consider this notification to have failed and will try again after some delay.

Important: The URL where you will receive Webhooks must be set up by our support team.

Common HTTP Status Code Responses

Successful Request Response (200)

{

"Id": "5efc3581-b8e8-11e7-9895-a6aabe61edb5",

"destination": [{

"id": "5efc3581-b8e8-11e7-9895-a6aabe61edb5",

"correlationId": "MyCorrelationId",

"destination": "5519900001111."

}]

}

If your request is successfully run, a list of destinations with the generated uuids will be returned:

Authentication Error Response (401)

{

"errorCode": 401,

"errorMessage": "Authentication Error: No user was found with this combination of username and Authentication token."

}

If a problem occurs with authentication, the following message will be returned:

Status Update Callback

Example

{

"total": 1,

"data": [

{

"id": "8995c40f-1c3a-48d0-98ee-bbc603622a91",

"correlationId": "...",

"destination": "5519900000000",

"origin": "5519900000000",

"campaignId": 100,

"campaignAlias": "...",

"flowId": "...",

"extraInfo": "...",

"sent": true,

"sentStatusCode": 1,

"sentStatus": "sent status",

"sentDate": "2017-12-18T17:09:31.891Z",

"sentAt": 1513616971891,

"delivered": true,

"deliveredStatusCode": 1,

"deliveredStatus": "delivered status",

"deliveredDate": "2017-12-18T17:09:31.891Z",

"deliveredAt": 1513616971891,

"read": true,

"readDate": "2017-12-18T17:09:31.891Z",

"readAt": 1513616971891,

"updatedDate": "2017-12-18T17:09:31.891Z",

"updatedAt": 1513616971891

}

],

"clientInfo": {

"customerId": 42,

"subAccountId": 1291,

"userId": 1

}

}

For every status update of sent messages (receipt of delivery to the end user, message read, etc.), a callback/webhook is sent. Callbacks are sent in bulk.

Important: The endpoint that the webhook will use to send statuses must be set up by our support and operations team.

The return format will have the following description:

Field

Details

Type

total

Number of callbacks in the call.

String

data

List of Callbacks.

Data[]

clientInfo

Client information.

ClientInfo

Data:

Field

Details

Type

id

Last message id.

String

correlationId

Unique ID set by you to compare to the message status (Callback and DLR). This parameter is optional, and you can use the ID generated by Wavy Messaging to compare.

String

destination

Phone number to which your message was sent (including country code). E.g.: 5511900000000.

String

origin

Phone number that identifies the WhatsApp Account (including country code). E.g.: 5511900000000.

String

campaignId

Previously set campaignID.

String

campaignAlias

Previously set campaign alias.

String

extraInfo

Extra information sent with the original message.

String

sent

Indicates whether the message has been sent.

Boolean

sentStatusCode

Status Code generated by Wavy Messaging for the message indicating its sent status.

Number

sentStatus

Sent status description.

Boolean

sentDate

Date the message was sent. Format: yyyy-MM-dd’T'HH:mm:ssZ.

String

sentAt

Time the message was sent, using Unix_time format

Number

delivered

Indicates whether the message has been delivered to its destination.

Boolean

deliveredStatusCode

Status Code generated by Wavy Messaging indicating whether the message has been delivered.

Number

deliveredStatus

Delivered status description.

String

deliveredDate

Date the message was delivered. Format: yyyy-MM-dd’T'HH:mm:ssZ

String

deliveredAt

Time the message was delivered, using Unix_time format

Number

read

Indicates whether the message has been read by the recipient.

Boolean

readDate

Date the message was read. Format: yyyy-MM-dd’T'HH:mm:ssZ

String

readAt

Time the message was read, using Unix_time format

String

updatedDate

Date the message status was updated. Format: yyyy-MM-dd’T'HH:mm:ssZ

String

updatedAt

Time the message status was updated, using Unix_time format

String

ClientInfo

Field

Details

Type

customerId

Customer identification.

Number

subAccountId

Subaccount identification.

Number

userId

User identification.

Number

Status

Statuses that can be sent in the callback:

Status

Sent Code

Delivery Code

Meaning

CARRIER_COMMUNICATION_ERROR

102

Error in uploading media to WhatsApp.

REJECTED_BY_CARRIER

103

A databank error has occurred.

SENT_SUCCESS

2

EXPIRED

2

101

Message expired.

Failure to send message because it is too old.

NOT_DELIVERED

2

104

Limit reached - too many attempts to send messages.

Failure to send message because this user’s phone number is part of an experiment.

Structure unavailable: Customer unable to display HSM.

Failure to send message because you are outside the support window for freely messaging this user. Please use a valid HSM notification or reconsider.

Error uploading media (unknown error).

Failure to send message because your account is ineligible. Please verify your WhatsApp Business account.

Temporary upload failure. Please try again later.

DELIVERED_SUCCESS

2

4

READ_SUCCESS

2

5

INVALID_DESTINATION_NUMBER

202

Invalid WhatsApp contact.

DESTINATION_BLOCKED_BY_OPTOUT

204

Destination blocked by Opt-Out.

INVALID_MESSAGE_LENGTH

206

Message is too long.

INVALID_MESSAGE_TEXT

207

Invalid parameter value.

INVALID_CONTENT

209

Invalid type of UNKNOWN message.

INVALID_SESSION

210

Session is not open and no fallback HSM is set up.

DESTINATION_BLOCKED_BY_OPTIN

211

DESTINATION_BLOCKED_BY_WHITELIST

212

INTERNAL_ERROR

311

Unable to verify WhatsApp API contacts.

MO (Messages Sent by the End User to the WhatsApp Account)

Text message example:

{

"total": 1,

"data": [

{

"id": "ce425ffe-bc62-421f-9261-e6819a5eab43",

"source": "5519900000000",

"origin": "5519900000000",

"userProfile": {

"name": "username"

},

"campaignId": 100,

"correlationId": "...",

"campaignAlias": "...",

"flowId": "....",

"extraInfo": "...",

"message": {

"type": "TEXT",

"messageText": "Hello, this is a user message."

},

"receivedAt": 1513616971473,

"receivedDate": "2017-12-18T17:09:31.473Z"

}

]

}

Extra Info example:

{

"segmentation_list":[

{

"id":26,

"customerId":42,

"subAccountId":0,

"name":"Movile WhatsApp Segmentation List",

"active":true

},

{

"id":27,

"customerId":43,

"subAccountId":0,

"name":"Movile WhatsApp Segmentation List 2",

"active":true

}

]

}

Media message example

{

"total": 1,

"data": [

{

"id": "ce425ffe-bc62-421f-9261-e6819a5eab43",

"source": "5519900000000",

"origin": "5519900000000",

"userProfile": {

"name": "username"

},

"campaignId": 100,

"correlationId": "...",

"campaignAlias": "...",

"flowId": "....",

"extraInfo": "...",

"message": {

"type": "IMAGE",

"mediaUrl": "https://...",

"mimeType": "image/jpg",

"caption": "..."

},

"receivedAt": 1513616971473,

"receivedDate": "2017-12-18T17:09:31.473Z"

}

]

}

Location message example:

{

"total": 1,

"data": [

{

"id": "ce425ffe-bc62-421f-9261-e6819a5eab43",

"source": "5519900000000",

"origin": "5519900000000",

"userProfile": {

"name": "username"

},

"campaignId": 100,

"correlationId": "...",

"campaignAlias": "...",

"flowId": "....",

"extraInfo": "...",

"message": {

"location": {

"geoPoint": "-22.894180,-47.047960",

"name": "Wavy",

"address": "Av. Cel. Silva Telles"

}

},

"receivedAt": 1513616971473,

"receivedDate": "2017-12-18T17:09:31.473Z"

}

]

}

Contact message example:

{

"total": 1,

"data": [

{

"id": "ce425ffe-bc62-421f-9261-e6819a5eab43",

"source": "5519900000000",

"origin": "5519900000000",

"userProfile": {

"name": "username"

},

"campaignId": 100,

"correlationId": "...",

"campaignAlias": "...",

"flowId": "....",

"extraInfo": "...",

"message": {

"contacts":[

{

"addresses":[

{

"city":"Menlo Park",

"country":"United States",

"country_code":"us",

"state":"CA",

"street":"1 Hacker Way",

"type":"HOME",

"zip":"94025"

},

{

"city":"Menlo Park",

"country":"United States",

"country_code":"us",

"state":"CA",

"street":"200 Jefferson Dr",

"type":"WORK",

"zip":"94025"

}

],

"birthday":"2012-08-18",

"emails":[

{

"email":"test@fb.com",

"type":"WORK"

},

{

"email":"test@whatsapp.com",

"type":"WORK"

}

],

"name":{

"first_name":"John",

"formatted_name":"John Smith",

"last_name":"Smith"

},

"org":{

"company":"WhatsApp",

"department":"Design",

"title":"Manager"

},

"phones":[

{

"phone":"+1 (940) 555-1234",

"type":"HOME"

},

{

"phone":"+1 (650) 555-1234",

"type":"WORK",

"wa_id":"16505551234"

}

],

"urls":[

{

"url":"https://www.fb.com",

"type":"WORK"

}

]

}

]

},

"receivedAt": 1513616971473,

"receivedDate": "2017-12-18T17:09:31.473Z"

}

]

}

For each reply from the end user (MO or Mobile Originated), a callback/webhook is sent. These MOs are sent in bulk.

Important: The endpoint that the webhook will use to send statuses must be set up by our support and operations team.

The return format will have the following description:

Field

Details

Type

total

Number of callbacks for the call.

String

data

List of Mobile Originated (MO) messages.

Data[]

Field

Details

Type

id

Last message identification

String

source

Sender’s phone number

String

origin

Phone number that identifies the WhatsApp Account (including country code). E.g.: 5511900000000.

String

userProfile

Profile of the user who sent the message

UserProfile

correlationId

Unique ID set by you to compare to the message status (Callback and DLR). This parameter is optional, and you can use the ID generated by Wavy Messaging to compare.

String

campaignId

Previously set campaignID.

String

campaignAlias

Previously set campaign alias.

String

message

MO message.

message

receivedAt

Date the message was received. Format: yyyy-MM-dd’T'HH:mm:ssZ

String

receivedDate

Date the message was received, using Unix_time format

String

extraInfo

Extra information related to the message. Format: Json

String

MO Flow Control - Segmentation Lists

The message will have a list of segmentation lists in the extraInfo field. Our partners use it to direct messages to certain flows. The key name is segmentation_lists and it contains a list of SegmentationList.

Field

Details

Type

id

Segmentation list identifier

Integer

customerId

Customer identifier

Integer

subAccountId

Subaccount identifier

Integer

name

Name of segmentation list

String

active

Status of segmentation list

Boolean

Message:

Field

Details

Type

type

Type of message sent to the end user: TEXT - IMAGE - AUDIO - DOCUMENT

String

messageText

Text message (MO) sent by the end user.

String

waGroupId

Group to which the message was sent.

String

mediaUrl

Url to download media sent by the end user.

String

mimeType

Mime type of the file sent by the end user.

String

caption

Media label sent by the end user.

String

location

Location sent by the end user.

Location

contacts

Contacts sent by the end user.

Contact[]

UserProfile:

Field

Required

Details

Type

name

No

User profile name

String

Location:

Field

Details

Type

name

Location name.

String

address

Location address.

String

geoPoint

Geopoint sent by the end user. Format: “latitude,longitude”

String

Contact:

Field

Required

Details

Type

addresses

No

Full address(es) of the contact.

Address[]

birthday

No

Birthday in YYYY-MM-DD format.

String

emails

No

Email address(es) of the contact.

Email[]

name

No

Full name of the contact.

Name

org

No

Information of the contact’s organization.

Org

phones

No

Phone number(s) of the contact.

Phone[]

urls

No

URL(s) of the contact.

Url[]

Address:

Field

Required

Details

Type

street

No

Street name and number.

String

city

No

City name.

String

state

No

State abbreviation.

String

zip

No

Zip code.

String

country

No

Full country name.

String

country_code

No

Country abbreviation (Two letters).

String

type

No

Default Values: HOME, WORK.

String

Email:

Field

Required

Details

Type

email

No

Email address.

String

type

No

Default Values: HOME, WORK.

String

Name:

Field

Required

Details

Type

first_name

No

First name.

String

last_name

No

Last name.

String

middle_name

No

Middle name.

String

name_suffix

No

Name suffix.

String

name_prefix

No

Name prefix.

String

formatted_name

No

Full name as it normally appears.

String

Org:

Field

Required

Details

Type

company

No

Name of the contact’s organization.

String

department

No

Name of the contact’s department.

String

title

No

Contact’s corporate title.

String

Phone:

Field

Required

Details

Type

phone

No

Formatted phone number.

String

type

No

Default values: CELL, MAIN, IPHONE, HOME, WORK.

String

wa_id

No

WhatsApp identifier.

String

Url:

Field

Required

Details

Type

phone

No

URL of the contact.

String

type

No

Default values: HOME, WORK.

String

For objects containing a type field, the listed values are simply considered default values that can be seen; however, you can set the field to any descriptive value you choose.

WhatsApp SFTP API

Connection Details

Hostname

ftp-messaging.wavy.global

Port

2222

Protocol

SFTP (transfer over ssh, providing client-server encryption)

Authentication

username + password (provided by support)

Your IPs must be allowed in Movile’s firewalls. If you need to allow outgoing traffic in the firewall for port 2222, you must allow the DNS, or IPs 200.219.220.54, 200.189.169.53 and 45.236.179.22

Sending Messages via SFTP

To trigger messages via FTP, you need to generate a file with formatting following the example below: HSM Message:

2018-10-16;10:00;20:00;HSM;chatclub_welcome;pt_BR;DETERMINISTIC;name|company phone;name;company 551999999999;Name1;Wavy 551999999999;Name2;Movile

1st Line

Send date (for scheduling cases)

Start send time (for scheduling cases)

End send time (for scheduling cases)

Message type must be: HSM

HSM name (elementName)

HSM language (languageLocale)

HSM language Deterministic or Fallback (languagePolicy)

name of HSM parameters

Notes for the First Line:

1 - Parameter names must match the column names

2 - Information that will not be used may be left blank, however you should keep the semicolon as separation. Example of a case where we did not use scheduling (the first fields are between semicolons and have no information within): ; ; ; HSM;chatclub_welcome;pt_BR;DETERMINISTIC;name|company

3 - By default, the languagePolicy will be Deterministic.

4 - The names of HSM parameters should be separated by “ | ” and not by “ ; ”

2nd Line

Column names

3rd and Remaining Lines:

Recipient and values of HSM parameters

Consulting Lists via API

Request

Using GET, you can make a request by sending all parameters in the query string

http://api-messaging.wavy.global/v1/list/{listType}?customerId={customerId}&subAccountId={subAccountId}

List Type

Value relayed in {listType}

Whatsapp OPT-OUT List

OPTOUT

Whatsapp OPT-IN List

OPTIN

Whatsapp Blacklist

BLACKLIST

Whatsapp Whitelist (for MT)

WHITELIST

The customerId parameter is required, while subAccountId is optional.

Attention: the ’{‘ and ’}‘ curly brackets must also be replaced. For example, “{listType}” becomes “OPTIN”.

You should also relay the following headers:

Header

Value

Content-Type

application/json

authenticationToken

Messaging1 token

userName

Messaging1 username

Response

If successful, if there is any data related to the customerId and subAccountId, the request will return a JSON with 3 attributes:

Attribute

Value

success

true

status

200

data

Link to download a csv file containing the “source” and “createdAt” fields of all destinations found

The “createdAt” column is in the America/Sao_Paulo time zone, UTC-3 or UTC-2 in Daylight Saving Time

If there is no associated data, only a similar JSON will be returned, but without the data field, which means no issues occurred with the request, but there weren’t any data related to the parameters relayed.

Response example:

{

"success": true,

"status": 200,

"data": "https://chatclub-cdn.wavy.global/2019/02/12/f2b8effb-d0bc-4327-86c2-48fedcb01b1b/list-42-4330544192402746957.csv"

}

Consulting Open Sessions via API

Request

To consult open sessions through our API, you need to make a GET request to the following URL:

GET http://api-messaging.wavy.global/v1/session?customerId={customerId}&subAccountId={subAccountId}

The customerId parameter is required, while subAccountId is optional.

Attention: The ’{‘ and ’}‘ curly brackets must also be replaced. For example, “={customerId}” becomes “=42”.

You should also relay the following headers:

Header

Value

Content-Type

application/json

authenticationToken

Token

userName

Username

Username and token can be obtained through our platform: https://messaging.wavy.global

Response

If successful, if there are any open sessions for the customerId and subAccountId, the request will return a JSON with the following attribute:

Attribute

Value

file_url

Link to download a csv file containing the “source” and “session_created_at” fields of all destinations found

If there are no data associated with the customerId and subAccountId, the returned file will be empty, containing only the header.

Response example:

{

"file_url": "https://chatclub-cdn.wavy.global/2019/02/13/633e33fc-3a3f-4ca5-a8b0-4b747fb67137/5bd46e2b-5990-4681-9b29-98ab6598960e"

}