Cendyn CRM API Icon

Webhooks


PushTech can make an HTTP POST to your URLs when events occurs. If you would like Pushtech to POST event notifications, you need to configure a callback URL in the Webhooks section in your account.


Configuration

In Api section of your account, you can find the Webhooks section. In this section you will find where to add your Urls to use with the webhook events. The webhook events are organised by channel for the delivery messages or organised by type for the contact activities.

HTTP status code

For Webhook POSTs, Pushtech listens for the following codes from your server and reacts accordingly:
  • if Pushtech receives a 200 (Success) code it will determine the webhook POST is successful and will not retry.

  • If Pushtech receives a 406 (Not Acceptable) code, it will determine the POST is rejected and will not retry.

  • For any other code, Pushtech will retry POSTing according to the schedule below for Webhooks other than the delivery events.

If your application is unable to process the webhook request but you do not return a 406 error code, Pushtech will retry (other than for delivery events) during 4 hours at the following intervals before stop trying: 5 minutes, 5 minutes, 10 minutes, 10 minutes, 30 minutes, 1 hour and 2 hours.

Securing Webhooks

To ensure the authenticity of each webhook requests, Pushtech signs them and posts the signature along with other webhook parameters:
Parameter Type Location Description
Account id string Body parameter String with your account ID
timestamp int Body parameter Number of seconds passed since January 1, 1970.
token string Body parameter Randomly generated string with length 50.
Authorization token string Authorization header String with hexadecimal digits generate by HMAC algorithm.

To verify the webhook is originating from Pushtech you need to:

  • Concatenate timestamp and token values.

  • Encode the resulting string with the HMAC algorithm (using your Account secret Key as a key and SHA256 digest mode).

  • Compare the resulting hexdigest to the Authorization token

  • Optionally, you can check if the timestamp is not too far from the current time.

Below is a PHP code sample used to verify the Authorization token:
function verify($account_secret_key, $token, $timestamp, $authorization) {
    $data = $timestamp . $token;
    return hash_hmac('sha256', $data, $account_secret_key) == $authorization;
}

And here’s a sample in Python:
import hashlib, hmac

def verify(account_secret_key, token, timestamp, authorization):
  hmac_digest = hmac.new(key=account_secret_key,
    msg='{}{}'.format(timestamp, token),
    digestmod=hashlib.sha256).hexdigest()
  return hmac.compare_digest(unicode(authorization), unicode(hmac_digest))

And here’s a sample in Ruby:
require 'openssl'
def verify(account_secret_key, token, timestamp, authorization)
  digest = OpenSSL::Digest::SHA256.new
  data = [timestamp, token].join
  authorization == OpenSSL::HMAC.hexdigest(digest, account_secret_key, data)
end

Reference

Activities events

Parameter Description
created_at The activity created date
_id The activity id
origin The origin of metric. Values [api, sdk, campaign]
type Describe the activity type. Values: [event, update, custom ,open_app , uninstall_app, subscribe_push, unsubscribe_push, add_cart, remove_cart,product_view , product_refund, purchase_failed, gps_location , contact_status]
event_type Describe a type of event related with campaigns. Values [opened, delivered, clicked, unsubscribed, sent, failed]
updated_field The name of field updated, only available if type is 'update'
updated_field_value The value of updated field, only available if type is 'update'
custom The custom raw metric,only available if type is 'custom' and origin is 'sdk'
custom_key The key of custom metric,only available if type is 'custom'
custom_value The value of custom metric,only available if type is 'custom'
old_status The old status of contact, only available if type is 'contact_status'
current_status Contact status, only available if type is 'contact_status'
contact[_id] Id of the contact
contact[user_id] Custom user_id of the contact
contact[device_id] Associated device_id
contact[name_first] First name of the contact
contact[name_last] Last name of the contact
contact[email] Email of the contact
contact[phone] Phone number with country code of the contact
app[_id] Id of app,only available if origin is 'sdk'
app[name] Name of the app,only available if origin is 'sdk'
app[icon] Icon of the app,only available if origin is 'sdk'
campaign[_id] Id of campaign,only available if origin is 'campaign'
campaign[name] Name of campaign,only available if origin is 'campaign'
product[UUID] Uniquee identifier of product, only available if type related with purchase or product
product[name] Name of product, only available if type related with purchase or product
product[price] Price of product, only available if type related with purchase or product
product[currency] Currency of product, only available if type related with purchase or product

Example of activity json:

{
  "created_at":"2016-12-09T15:28:28Z",
  "_id":"584acd9c85216d892f000002",
  "origin":"campaign",
  "type":"event",
  "event_type":"sent",
  "contact": {
    "_id": "584acff2f92ea1bcf7000012",
    "user_id": "jhon_doe",
    "name_first": "Jhon",
    "name_last": "doe",
    "email": "Jhon.doe@cendyn.com",
    "phone": "+346xxxxxxxx",
    "device_id": "5848408485216d13d1000009"
  },
  "campaign":{
    "_id":"5848408485216d13d100000a",
    "name":"Welcome email"
  },
  "timestamp":1481297309,
  "token":"9ykzr1m09d3jgq04k5j2htlf0rs7wy93rtniaes6v3lyk2scm7",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Delivery events

Parameter Description
id The delivery id
created_at The delivery created date
updated_at The delivery updated date
channel The delivery channel, Values : [sms, push, email]
status The status of delivery, Values : [none, queued, sent, deliverd, opened, clicked, rejected, undefined, undelivered, forbidden_country_code, failed, bounced, unsubscribed, dropped, complained]
refunded If true refunded the money in your account
url Url only available if status is clicked and represent the user url clicked
campaign[_id] Id of campaign, only available if delivery created in Pushtech.com Manager
campaign[name] Name of campaign, only available if delivery created in Pushtech.com Manager
template[_id] Id of template, only available if delivery created in Pushtech.com Manager and channel is email
template[name] Name of template, only available if delivery created in Pushtech.com Manager and channel is email
template_data[sender] Sender of email, only available if delivery created in Pushtech.com Manager and channel is email
template_data[subject] Subject of email, only available if delivery created in Pushtech.com Manager and channel is email
template_data[content] Content of sms or push message, only available if delivery created in Pushtech.com Manager and channel is push or sms
template_data[reply_to] Email to reply to, only available if delivery created in Pushtech.com Manager and channel is email
landing_page_sms[_id] Id of landing page, only available if delivery created in Pushtech.com Manager and channel is sms and contains a landing page link
landing_page_sms[name] Name of landing page, only available if delivery created in Pushtech.com Manager and channel is sms and contains a landing page link
landing_page_sms[url] Url of landing page, only available if delivery created in Pushtech.com Manager and channel is sms and contains a landing page link
landing_page_push[_id] Id of landing page, only available if delivery created in Pushtech.com Manager and channel is push and contains a landing page link
landing_page_push[name] Name of landing page, only available if delivery created in Pushtech.com Manager and channel is push and contains a landing page link
landing_page_push[url] Url of landing page, only available if delivery created in Pushtech.com Manager and channel is push and contains a landing page link
channel_data Data of delivery
contact[_id] Id of the contact, only available if campaign sent with Pushtech.com Manager
contact[user_id] Custom user_id of the contact
contact[name_first] First name of the contact, only available if campaign sent with Pushtech.com Manager
contact[name_last] Last name of the contact, only available if campaign sent with Pushtech.com Manager
contact[email] Email of the contact, only available if campaign sent with Pushtech.com Manager
contact[phone] Phone number with country code of the contact
app[_id] Id of app,only available if campaign sent with Pushtech.com Manager and channel is push
app[name] Name of the app,only available if campaign sent with Pushtech.com Manager and channel is push
app[icon] Icon of the app,only available if campaign sent with Pushtech.com Manager and channel is push
device[_id] Id of device,only available if campaign sent with Pushtech.com Manager and channel is push
device[type] type of the device (ios, android or web), only available if campaign sent with Pushtech.com Manager and channel is push
device[device_push_token] Push token of the device, only available if campaign sent with Pushtech.com Manager and channel is push

Example of delivery json:

 {
  "id":"584acffdf92ea1e99a000001",
  "created_at":"2016-12-09T15:38:37Z",
  "updated_at":"2016-12-09T15:38:49Z",
  "channel":"EMAIL",
  "status":"delivered",
  "refunded":false,
  "url":null,
  "campaign":{
    "_id":"5848408485216d13d100000a",
    "name":"Welcome"
  },
  "template"{
   "_id": "5848408485216d13d1000009",
   "name" : "Welcome"
  },
  "template_data":{
    "sender":"Cendyn CRM platform ",
    "subject":"",
    "content":"",
    "reply_to":""
  },
  "channel_data":{
    "3":"Jhon.doe@cendyn.com"
  },
  "contact": {
    "_id": "584acff2f92ea1bcf7000012",
    "user_id": "jhon_doe",
    "name_first": "Jhon",
    "name_last": "doe",
    "email": "Jhon.doe@cendyn.com",
    "phone": "+346xxxxxxxx",
    "device_id": "5848408485216d13d1000009"
  },
  "timestamp":1481297931,
  "token":"mcnwldwmullbg4wkcx33ewirm4kmi5vn1i9k30hob5vagdk69w",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Bulk contacts

Parameter Description
contacts_valid_count Number of contacts saved in Cendyn CRM
contacts_failed_count Number of contacts failed to save in Cendyn CRM
failed_contacts Array that contains failed contacts
failed_contacts[contact] Contact params of a particular failed contact
failed_contacts[error] Description because contact save failed
valid_contacts Array that contains a valid contacts with basic fields: _id, user_id, email, phone_countrycode , phone_number
valid_contacts[_id] Pushtech id of the contact
valid_contacts[user_id] User id of the contact
valid_contacts[email] Email of the contact
valid_contacts[phone_countrycode] Phone country code of the contact
valid_contacts[phone_number] Phone number of the contact

Example of bulk json:

{
  "contacts_valid_count":3,
  "contacts_failed_count":1,
  "failed_contacts":[
                    {
                      "contact":
                        {
                          "name_first":"Doria",
                          "name_last":"Leppiwell",
                          "city":"Shajia’ao",
                          "gender":"Female",
                          "email":"badformat",
                        },
                        "errors":["Email format not recognised"]

                    }
                    ],
  "valid_contacts":[
                  {
                    "_id":"599bf99af70366f2be000001",
                    "user_id":"1",
                    "email":"dleppingwell0@mydomain.com",
                    "phone_countrycode":"34",
                    "phone_number":866666666
                  },
                  {
                    "_id":"599bf99af70366f2be000002",
                    "user_id":"3",
                    "email":"kschapiro1@domain.gov",
                    "phone_countrycode":34,
                    "phone_number":566678888
                  },
                  {
                    "_id":"599bf99af70366f2be000003",
                    "user_id":"2",
                    "email":"acasazza2@domainmarket.com",
                    "phone_countrycode":34,
                    "phone_number":877777777
                  }
                  ],
  "timestamp":1503394216,
  "token":"2m93z8xw1ofoiy890xx23ql9ah0gz60t85nuc9wyshu5apjxtt",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Incoming SMS

Parameter Description
id The incoming sms identificator
received_at Date of received sms
text Message text
from Phone number that send this text message

Example of incoming sms json:

{ "id": "599bf99af70366f2be000001",
  "received_at":"2018-01-23T15:38:37Z",
  "text":"This simple message text",
  "from":"346xxxxxxxx",
  "timestamp":1503394216,
  "token":"2m93z8xw1ofoiy890xx23ql9ah0gz60t85nuc9wyshu5apjxtt",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Contact Events

Parameter Description
action Define the action of contact event. Values: create, channel_subscription, update, destroy
origin Origin of event, Values: sdk, platform_individual, platform_bulk, validation, campaign
origin_sdk type of device (ios, android or web), only available if origin is sdk
contact Contact information like GET request, if action is create and origin is platform_individual
contact[id] Pushtech id of the contact
contact[user_id] User id of the contact
contact[changes] A JSON with keys of the changed field and the new value. Only available for the action update and origin platform_individual or sdk
contact[contact_url] An url to Get the full contact information by API. Only available for the action update and origin platform_individual or sdk
contacts_ids An array of contact_ids, only available if origin is platform_bulk
user_ids An array of user_ids, only available if origin is platform_bulk
channel_subscription Contact subscription information, if action is subscription
channel_subscription[channel] Channel name of subscription status
channel_subscription[blacklisted] If true this channel is blacklisted
channel_subscription[origin] origin of the event
channel_subscription[date] Date and Time when this event occured

Example when a contact is created on the platform

{
  "action": "create",
  "origin": "platform_individual",
  "contact": {
    "id": "5b6d50651a7e4ef63e000005",
    "name_first": "Jhon",
    "list_subscriptions": [],
    "name_last": "Doe",
    "phone_countrycode": "xx",
    "phone_number": "xxxxxxxxx",
    "user_id": xxx,
    "city": xxx,
    "gender": xxx,
    "country": xxx,
    "language": xxx,
    "facebook_id": xxx,
    "facebook_friends": xxx,
    "google_id": xxx,
    "twitter_id": xxx,
    "twitter_followers": xxx,
    "born_date": xxx,
    "email": "jhon.do3@cendyn.com",
    "gdpr_marketing_consent": true,
    "gdpr_accept_terms": true,
    "gdpr_date": 2018-07-09T15:28:28Z,
    "gdpr_remote_ip": xxxxxx,
    "gdpr_link_terms": xxxxxx,
    "gdpr_link_privacy": xxxxxx,
    "tags": [],
    "company_id": xxxx,
    "company_name": xxxx
  },
  "timestamp": 1533890854,
  "token": "dtz2gbeqb556ayg2z9hwe4mgdn1or1qw7utaigiiaf8b9t5f1a",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Example when a contact changed subscription email channel by api

{
  "action": "channel_subscription",
  "origin": "api",
  "contact_id": "5b6d96991a7e4e8ac8000128",
  "user_id":"6712",
  "subscription":{
    "channel":"email",
    "blacklisted":true,
    "origin":"api"
  }
  "timestamp": 1533909631,
  "token": "gvqmo9vm671pf8cnp5iwnqiwtxw7csc6u8v1p8uukn23g4yjxc",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Example when a contact is updated on the platform

{
  "action": "update",
  "origin": "platform_individual",
  "contact": {
    "id": "5b6d96991a7e4e8ac8000128",
    "user_id": "6712",
    "changes": {
      "city": "New York"
    },
    "contact_url": "https://api.eu.cendyncrm.com/v2/account/5a9eb2cd1a7e4e6b6f000007/contact/5b6d96991a7e4e8ac8000128"
  },
  "timestamp": 1533909631,
  "token": "gvqmo9vm671pf8cnp5iwnqiwtxw7csc6u8v1p8uukn23g4yjxc",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Example bulk contacts destroy on the platform

{
  "action": "destroy",
  "origin": "platform_bulk",
  "contacts_ids": [
    "5b6d96991a7e4e8ac8000002",
    "5b6d96991a7e4e8ac8000003"
  ],
  "users_ids": [
    "9673",
    "8086"
  ],
  "timestamp": 1533908635,
  "token": "a8uau26zd3gqtkbh3m5wrp9ipac1fxjnsg4wsbg9xam6loadu9",
  "account_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}