DOCUMENTATION

Webhook Journey Nodes

Webhooks

Webhook Nodes

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 certain 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

Field Type Description
site Site Contains information about the site that sent the webhook
customer Customer Contains information about the customer in the journey
cart Cart or null Contains information about the cart and cart items for the session, if they exist
contact Contact or null Contains information about the email list contact related to the customer's journey, if it exists
customer_journey CustomerJourney Contains information about the customer's specific journey
journey Journey Contains information about the journey which contains the node which is sending the webhook
journey_node JourneyNode Contains information about the specific node which is sending the webhook
session Session Contains information about the session in the journey
metadata Metadata Contains static key-value pairs which can be defined as part of the webhook configuration

Site

Field Type Description
id String The Rejoiner ID for the site
url String The URL for the site
timezone String The configured timezone for the site
currency String The configured currency for the site

Customer

Field Type Description
id String The Rejoiner ID for the customer
email String The email address for the customer
first_name String The customer's first name
last_name String The customer's last name
phone String The customer's phone number
timezone String The customer's timezone
age Integer The customer's age
gender String The customer's gender (one of m or f)
language String The two-letter language code for the customer
address1 String The first line of the customer's address
address2 String The second line of the customer's address
address3 String The third line of the customer's address
city String The city of the customer's address
state String The state code of the customer's address
postal_code String The postal code of the customer's address
country String The country code of the customer's address
birthdate Date or null The customer's birthdate
tags Array of Strings Rejoiner tags associated with the customer

Cart

Field Type Description
return_url String The URL which should regenerate the cart of the customer
promo String The promo code used for the cart
order_number String The order number associated with the cart
value Integer The value (in cents) of the cart
item_count Integer The number of items in the cart
metadata Metadata Key-value pairs of custom data associated with the cart
cart_items Array of CartItems Information about the items in the cart

CartItem

Field Type Description
product_id String The product ID of the cart item (e.g. SKU)
name String The name of the cart item
price Integer The unit price (in cents) of the cart item
product_url String The URL of the product on the site
image_url String The URL of the product's image
description String The description of the cart item
categories Array of Strings The categories associated with the cart item
qty Integer The amount of the product added to the cart
total_price Integer The total price (in cents) for the total quantity of this product in the cart
metadata Metadata Key-value pairs of custom data associated with the cart item

Contact

Field Type Description
custom_fields Metadata Key-value pairs of custom data associated with the email list contact

CustomerJourney

Field Type Description
id String The Rejoiner ID for the specific customer's current journey
start_date Datetime The date and time at which the customer started the journey
finish_date Datetime The date and time at which the customer has exited the journey

Journey

Field Type Description
id String The Rejoiner ID for the journey which triggered the webhook
name String The name of the journey
options String The options configured for the journey
trigger String The trigger type of the journey

JourneyNode

Field Type Description
id String The Rejoiner ID for the journey node which triggered the webhook
action String The type of action the node performs
display String The display name for the journey node
audience JourneyNode Information about the audience the journey node belongs to

Session

Field Type Description
id String The Rejoiner ID for the session currently in the journey
status String The current status of the session in the journey
abandon_date Datetime or null The date and time at which the session was abandoned
convert_date Datetime or null The date and time at which the session was converted
delivery_date Datetime or null The date and time at which the session was delivered
fulfillment_date Datetime or null The date and time at which the session was fulfilled
payment_date Datetime or null The date and time at which the session was paid
metadata Metadata Key-value pairs of custom data associated with the session
viewed_products Array of Products Information about the products that were viewed during the session

Product

Field Type Description
product_id String The product ID of the product (e.g. SKU)
name String The name of the product
price Integer The unit price (in cents) of the product
product_url String The URL of the product on the site
image_url String The URL of the product's image
description String The description of the product
categories Array of Strings The categories associated with the product

Sample Payload

{
    "site": {
        "id": "abcdefg",
        "url": "http://example.com",
        "currency": "USD",
        "timezone": "America/New_York"
    },
    "customer": {
        "id": "abcdefg",
        "email": "john.doe@example.com",
        "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 recieves a 2xx response from your server. If any other response is returned, the webhook will be retried with an 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.

Back to Top