1. Home
  2. Webhooks & APIs
  3. Verloop Campaign API
  • User Guide
  • Developer Docs
Frequently visited sections What is verloop?, FAQ Overview?

Verloop Campaign API

Introduction:

Welcome to the Campaign Verloop API. Verloop API lets you send messages to your users on WhatsApp and other channels (coming soon)

API Version:

The current version of the API V1.0

Reference:

Following are the use cases of Verloop Campaign API.

  1. Get the list of templates (live)
  2. Get a template (live)
  3. Get the list of campaigns (live)
  4. Get a campaign (live)
  5. Trigger a template message as a part of a campaign (live)
  6. Callbacks (live)

Postman collection: https://www.getpostman.com/collections/8e64c8f29c726d4e9dc2

Concepts:

Client ID

<client_id> can be found in the verloop dashboard URL (the part before verloop.io). for example, in https:/clientID.verloop.io, the client id would be “bigbasket”

So the endpoint URL for Send Message would be: https://clientID.verloop.io/api/v1/Campaign/SendMessage

API Errors:

We use Twirp for serving, so overall status codes can be found in this document.

Errors specific to this API can be “unauthenticated”, “not_found”, “internal” or “invalid_argument” type

Auth Token

A valid auth token will be necessary to send campaign messages. It’ll be shared separately over email/UI. This token must be sent in the `Authorization` header with all requests.

If you send an incorrect/ expired/revoked auth token, the API will respond with status 401 and the following body

{
  "code": "unauthenticated",
  "msg": "Authentication required"
}

Meta:

Every object in Verloop across all APIs has meta information in this field.

IdString (Id of the object)
CreatedAtUnix timestamp of create time
UpdatedAtUnix timestamp of last updated time

List Templates:

Request:

Method: POST

URL:  https://<client_id>.verloop.io/api/v1/Campaign/ListTemplates

Headers: 

Authorization: <auth_token>

Content-Type: application/json

Body:

{
  "ListOption": {
    "Limit": 10,
    "Offset": 0
  },
  "Type": "TYPE_WHATSAPP"
}

Response:

Success:

{
  "ListOption": {
    "Limit": 10,
    "Offset": 0
  },
  "Count": 2,
  "Templates": [
    {
      "Meta": {
        "Id": "1234",
        "CreatedAt": 1564996815,
        "UpdatedAt": 1564996815
      },
      "Name": "Order Confirmed WA",
      "WhatsAppTemplate": {
        "TemplateID": "order_confirmed1"
      },
      "Block": {
        "MessageBlock": {
          "Type": "TYPE_MESSAGE",
          "LeadingMessage": {
            "TextMessage": "Your order {{order_number}} for {{amount}} has been confirmed"
          }
        }
      },
      "Parameters": ["order_number", "amount"]
    },
    {
      "Meta": {
        "Id": "4567",
        "CreatedAt": 1564996800,
        "UpdatedAt": 1564996800
      },
      "Name": "Happy birthday WA",
      "WhatsAppTemplate": {
        "TemplateID": "happy_birthday1"
      },
      "Block": {
        "MessageBlock": {
          "Type": "TYPE_MESSAGE",
          "LeadingMessage": {
            "TextMessage": "Happy birthday!\n\nAvail {{discount}} off on your birthday, use coupon code {{coupon_code}}"
          }
        }
      },
      "Parameters": ["discount", "coupon code"]
    }
  ]
}

Error:

Status: 400

{
  "code": "invalid_argument",
  "msg": "ListOption.Limit is capped at 100",
  "meta": {
    "argument": "ListOption.Limit"
  }
}

Get Template:

Request:

Method: POST

URL:  https://<client_id>.verloop.io/api/v1/Campaign/GetTemplate

Headers: 

Authorization: <auth_token>

Body:

{
  "ID": "1234"
}

Response:

Success:

{
  "Template": {
    "Meta": {
      "Id": "1234",
      "CreatedAt": 1564996815,
      "UpdatedAt": 1564996815
    },
    "Name": "Order Confirmed WA",
    "WhatsAppTemplate": {
      "TemplateID": "order_confirmed1"
    },
    "Block": {
      "MessageBlock": {
        "Type": "TYPE_MESSAGE",
        "LeadingMessage": {
          "TextMessage": "Your order {{order_number}} for {{amount}} has been confirmed"
        }
      }
    },
    "Parameters": ["order_number", "amount"]
  }
}

Error:

Status: 404

{
  "code": "not_found",
  "msg": "Template not found"
}

List Campaigns:

Request:

Method: POST

URL:  https://<client_id>.verloop.io/api/v1/Campaign/ListCampaigns

Headers: 

Authorization: <auth_token>

Content-Type: application/json

Body:

{
  "ListOption": {
    "Limit": 10,
    "Offset": 0
  },
  "Type": "TYPE_WHATSAPP"
}

Response:

Success:

{
  "ListOption": {
    "Limit": 10,
    "Offset": 0
  },
  "Count": 2,
  "Campaigns": [
    {
      "Meta": {
        "Id": "abcd",
        "CreatedAt": 1564996815,
        "UpdatedAt": 1564996815
      },
      "Name": "Order update",
      "Type": "TYPE_WHATSAPP",
      "TemplateID": "1234",
      "Status": "STATUS_DRAFT"
    },
    {
      "Meta": {
        "Id": "defg",
        "CreatedAt": 1564996805,
        "UpdatedAt": 1564996813
      },
      "Name": "Birthday discount",
      "Type": "TYPE_WHATSAPP",
      "TemplateID": "4567",
      "Status": "STATUS_PUBLISHED"
    }
  ]
}

Error:

Status: 400

{
  "code": "invalid_argument",
  "msg": "ListOption.Limit is capped at 100",
  "meta": {
    "argument": "ListOption.Limit"
  }
}

Get Campaign:

Request:

Method: POST

URL:  https://<client_id>.verloop.io/api/v1/Campaign/GetCampaign

Headers: 

Authorization: <auth_token>

Content-Type: application/json

Body:

{

    “ID”: “abcd”

}

Response:

Success:

{
  "Campaign": {
    "Meta": {
      "Id": "abcd",
      "CreatedAt": 1564996815,
      "UpdatedAt": 1564996819
    },
    "Name": "My updated campaign name",
    "Type": "TYPE_WHATSAPP",
    "TemplateID": "4567",
    "Status": "STATUS_PUBLISHED"
  }
}

Error:

Status: 400

{
  "code": "invalid_argument",
  "msg": "Campaign.Meta.Id is required",
  "meta": {
    "argument": "Campaign.Meta.Id"
  }
}

Send Message

Request:

Method: POST

URL:  https://<client_id>.verloop.io/api/v1/Campaign/SendMessage

Headers: 

Authorization: <auth_token>

Content-Type: application/json

Body:

{
  "CampaignID": "abcd",
  "To": {
    "PhoneNumber": "919916564955"
  },
  "Parameters": {
    "order_number": "#1234",
    "amount": "$100"
  },
  "Variables": {
    "order_number": "1234",
    "customer_id": "my_customer_id"
  },
  "Callback": {
    "URL": "https://example.com/msg_callback",
    "State": {
      "a": "b",
      "c": "d"
    }
  }
}

Response:

Success:

{

   "MessageID": "some_message_id"

}

Error:

Status: 400

{
  "code": "invalid_argument",
  "msg": "Callback.URL not a valid HTTPS URL",
  "meta": {
    "argument": "Callback.URL"
  }
}

Possible Errors:

  • CampaignID is not valid
  • CampaignID is not published
  • CallbackURL is not a valid HTTPS URL
  • CallbackURL only HTTPS callback URLs are allowed
  • WhatsAppCampaignParameters are not present or valid
  • Couldn’t send campaign message, please retry in some time

CampaignID: As of now, you cannot send a templated whatsapp message without a campaign id. When you create a campaign, you get a campaign id, you have to pass that here.

PhoneNumber: PhoneNumber is with the 91 India code, so you have to use the number of the customer as WhatsApp saves it, with preceding country code without 0 or +. E.g. 919689639098

Parameters: Template Messages have parameters that will be dynamically incorporated into the message. These parameters will be passed in Parameters in the form of a dictionary of string key value pairs. 

  • Note: Sending more or fewer params than a template expects will result in a silent failure as we don’t know that status from Kaleyra yet.
  • In the example above, `$100` has no meaning outside of passing straight to WhatsApp/ any channel we support in the future.
  • Parameter values being sent must be in stringified format. i.e. even if `amount` was supposed to be an integer, it must be sent to the API as a string

Variables: These are the Verloop variables that will be associated with the user when the user engages with the template message. These variables will be available during recipe for interpolation/webhook block and exports, this is where you can send variables. These are completely independent of `LocalizableParams`.

  • In the example above, `$100` is not available in the recipe. If you want to use it in the recipe, you can send it in Variables.
  • Variables being sent must be defined beforehand from the UI, this allows us to parse and validate them later. Any variables not set on the UI will be dropped completely.
  • Variables being sent must be in stringified format. i.e. even if `order_number` was supposed to be an integer, it must be sent to the API as a string.

CallbackURL: If you need status updates for Messages, you can send a https URL in this parameter. We’ll make a POST request with in application/json format with the following body

Sample body:

{
  "MessageID": "some_message_id",
  "Status": "STATUS_READ",
  "Timestamp": 1564996815,
  "Parameters": {
    "order_number": "#1234",
    "amount": "$100"
  },
  "Variables": {
    "order_number": "1234",
    "customer_id": "my_customer_id"
  },
  "State": {
    "a": "b",
    "c": "d"
  }
}

MessageID:

Id of the message as sent in response to the SendMessage API.

Status:

StatusMeaning
STATUS_PENDINGInitial status of every message (not sent over callback)
STATUS_SENTMessage was sent to the user
STATUS_DELIVEREDMessage delivered to user
STATUS_READMessage read by user
STATUS_REPLIEDUser replied to the message
STATUS_EXPIREDA new campaign message expired old campaign messages (future: campaign had an expiry which lapsed)
STATUS_FAILEDMessage could not be sent to the user.

Note: In a future version of the callback API, we will start adding a field for “Reason” of failure in case of STATUS_FAILED.

Timestamp:

Time of status event in seconds since unix epoch.

Parameters and Variables:

Same as above.

SendMessage gotchas:

  • In this initial version, the API accepts any campaign ID and variable name/value you’re sending and will silently drop it without warning. In a future version, we will add checks and return an error in the `SendMessage` API itself.
  • You can only send messages after a campaign has been published. An unpublished Campaign will silently drop messages for now, in a later version `SendMessage` will return an error. (We might need to implement testing endpoints and/or UI senders with rate budgets to test unpublished campaigns)

Campaign ⇒ Template + Associated workflow

Collect Moviefeedback_1 ⇒ collect_NPS_movie_1 + Collect NPS

Collect MF_2 ⇒ collect_NPS_movie_2 + Collect NPS

Send_20_discount ⇒ whatsapp_template_discount_20 + default

Updated on October 26, 2023

Was this article helpful?

Related Articles

Schedule a demo

Get Started with Verloop.io