Webhooks

Webhook nodes provide the ability for you to send information about a customer in a journey
to external services. When a webhook node is processed, a payload is sent to the specified URL
with information about the journey and journey node it came from, as well as information about the
customer and session currently being processed by that node.

This can allow you to build a receiver that can be notified when a customer has reached a point in their journey, which would allow you to do whatever you'd like, including notifying other
software with updates about the customer.

Payload

The payload for webhook nodes consists of a complete picture of the customer, session, and their current
status within a journey. The payload is always JSON format. A description of the fields of the payload is below:

Top-Level Fields

FieldTypeDescription
siteSiteContains information about the site that sent the webhook
customerCustomerContains information about the customer in the journey
cartCart or nullContains information about the cart and cart items for the session, if they exist
contactContact or nullContains information about the email list contact related to the customer's journey, if it exists
customer_journeyCustomerJourneyContains information about the customer's specific journey
journeyJourneyContains information about the journey which contains the node which is sending the webhook
journey_nodeJourneyNodeContains information about the specific node which is sending the webhook
sessionSessionContains information about the session in the journey
metadataMetadataContains static key-value pairs which can be defined as part of the webhook configuration

Site

FieldTypeDescription
idStringThe Rejoiner ID for the site
urlStringThe URL for the site
timezoneStringThe configured timezone for the site
currencyStringThe configured currency for the site

Customer

FieldTypeDescription
idStringThe Rejoiner ID for the customer
emailStringThe email address for the customer
first_nameStringThe customer's first name
last_nameStringThe customer's last name
phoneStringThe customer's phone number
timezoneStringThe customer's timezone
ageIntegerThe customer's age
genderStringThe customer's gender (one of m or f)
languageStringThe two-letter language code for the customer
address1StringThe first line of the customer's address
address2StringThe second line of the customer's address
address3StringThe third line of the customer's address
cityStringThe city of the customer's address
stateStringThe state code of the customer's address
postal_codeStringThe postal code of the customer's address
countryStringThe country code of the customer's address
birthdateDate or nullThe customer's birthdate
tagsArray of StringsRejoiner tags associated with the customer

Cart

FieldTypeDescription
return_urlStringThe URL which should regenerate the cart of the customer
promoStringThe promo code used for the cart
order_numberStringThe order number associated with the cart
valueIntegerThe value (in cents) of the cart
item_countIntegerThe number of items in the cart
metadataMetadataKey-value pairs of custom data associated with the cart
cart_itemsArray of CartItemsInformation about the items in the cart

CartItem

FieldTypeDescription
product_idStringThe product ID of the cart item (e.g. SKU)
nameStringThe name of the cart item
priceIntegerThe unit price (in cents) of the cart item
product_urlStringThe URL of the product on the site
image_urlStringThe URL of the product's image
descriptionStringThe description of the cart item
categoriesArray of StringsThe categories associated with the cart item
qtyIntegerThe amount of the product added to the cart
total_priceIntegerThe total price (in cents) for the total quantity of this product in the cart
metadataMetadataKey-value pairs of custom data associated with the cart item

Contact

FieldTypeDescription
custom_fieldsMetadataKey-value pairs of custom data associated with the email list contact

CustomerJourney

FieldTypeDescription
idStringThe Rejoiner ID for the specific customer's current journey
start_dateDatetimeThe date and time at which the customer started the journey
finish_dateDatetimeThe date and time at which the customer has exited the journey

Journey

FieldTypeDescription
idStringThe Rejoiner ID for the journey which triggered the webhook
nameStringThe name of the journey
optionsStringThe options configured for the journey
triggerStringThe trigger type of the journey

JourneyNode

FieldTypeDescription
idStringThe Rejoiner ID for the journey node which triggered the webhook
actionStringThe type of action the node performs
displayStringThe display name for the journey node
audienceJourneyNodeInformation about the audience the journey node belongs to

Session

FieldTypeDescription
idStringThe Rejoiner ID for the session currently in the journey
statusStringThe current status of the session in the journey
abandon_dateDatetime or nullThe date and time at which the session was abandoned
convert_dateDatetime or nullThe date and time at which the session was converted
delivery_dateDatetime or nullThe date and time at which the session was delivered
fulfillment_dateDatetime or nullThe date and time at which the session was fulfilled
payment_dateDatetime or nullThe date and time at which the session was paid
metadataMetadataKey-value pairs of custom data associated with the session
viewed_productsArray of ProductsInformation about the products that were viewed during the session

Product

FieldTypeDescription
product_idStringThe product ID of the product (e.g. SKU)
nameStringThe name of the product
priceIntegerThe unit price (in cents) of the product
product_urlStringThe URL of the product on the site
image_urlStringThe URL of the product's image
descriptionStringThe description of the product
categoriesArray of StringsThe categories associated with the product

Sample Payload

{
    "site": {
        "id": "abcdefg",
        "url": "http://example.com",
        "currency": "USD",
        "timezone": "America/New_York"
    },
    "customer": {
        "id": "abcdefg",
        "email": "[email protected]",
        "first_name": "John",
        "last_name": "Doe",
        "phone": "867-5309",
        "gender": "m",
        "timezone": "America/New_York",
        "age": 30,
        "language": "en",
        "country": "USA",
        "tags": ["foo", "bar"],
        "address1": "",
        "address2": "",
        "address3": "",
        "city": "",
        "state": "",
        "postal_code": "",
        "birthdate": null
    },
    "cart": {
        "cart_items": [],
        "item_count": 4,
        "metadata": {},
        "order_number": "12345678910",
        "promo": "PROMO",
        "return_url": "http://example.com/cart/",
        "value": 4000
    },
    "contact": null,
    "customer_journey": {
        "id": "abcdefg",
        "finish_date": null,
        "start_date": "2019-01-01T10:30:00"
    },
    "journey": {
        "id": "abcdefg",
        "name": "Cart Abandon",
        "options": "",
        "trigger": "Cart Abandon"
    },
    "journey_node": {
        "id": "abcdefg",
        "action": "Send Webhook",
        "audience": {
            "id": "abcdefg",
            "action": "Audience",
            "display": "Catch-All"
        }
    },
    "metadata": {
        "custom_webhook": "metadata",
        "foo": "bar"
    },
    "session": {
        "abandon_date": "2019-01-01T11:30:00",
        "convert_date": null,
        "delivery_date": null,
        "fulfillment_date": null,
        "id": "12345678910",
        "metadata": {},
        "payment_date": null,
        "start_date": "2019-01-01T10:30:00",
        "status": "abandoned_cart",
        "viewed_products": [
            {
                "date": "2019-01-01T10:30:00",
                "product": {
                    "categories": ["default", "test"],
                    "description": "This is a test product.",
                    "expiration_date": null,
                    "image_url": "http://via.placeholder.com/150",
                    "name": "Test Product",
                    "price": 3400,
                    "product_id": "ProductID-0",
                    "product_url": "http://example.com/test-product"
                }
            }
        ]
    }
}

Webhook Signatures

All webhooks are signed using a secret key unique to your site which you can
use to verify that the payload has not been tampered with. This is not strictly
necessary but is recommended to ensure the accuracy of your data.

Rejoiner generates signatures using a hash-based message authentication code
(HMAC) and SHA-1. You can verify a signature
by following these steps:

  1. Extract the timestamp and the signature from the X-RJ-Signature header on the request.
    The timestamp value is prefaced with t= and the signature value is prefaced with sha1=.

  2. Prepare the signed payload string. The payload used to generate the signature can be generated by concatenating the following:

    • The timestamp value extracted from the header
    • The period character: `.`
    • The actual JSON payload of the request (i.e. the request body)
  3. Generate the signature by computing an HMAC with your site's webhook secret as
    the key and the signed payload string as the message.

  4. Compare your generated signature with the signature in the request. If the two
    signatures match, then compare the current timestamp with the request's timestamp
    and decide if the difference between them is within your tolerance.

Retries and Rate Limits

Rejoiner will attempt to send a webhook up to 5 times until it succeeds. A webhook
is considered to be successfully delivered if it receives a 2xx response from
your server. If any other response is returned, the webhook will be retried with
exponential backoff to avoid sending too many messages at once that may fail.

Additionally, if your endpoint results in greater than an 80% failure rate within
one hour, Rejoiner will only attempt to send a webhook once. This is done to avoid
sending too many messages to a non-responsive server by retrying every failed message
but to still allow messages to be received if a server comes back online.