Email Sync Webhook API

Email Sync Webhook API

This REST API, which you implement on your system, allows Kahuna to send unsubscribe, bounce, and spam information it receives as it runs your campaigns. This information helps you avoid sending an erroneous email from your own system if Kahuna has already detected the error.

To ensure Kahuna can transmit its information to you, use the following REST specifications when you implement your API.

REST API Incoming Request Specification

HTTPS Endpoint
  1. Create an HTTPS endpoint in a web server in your system. For example:


  2. Contact your Kahuna Customer Success specialist and ask to register your endpoint.
Signature Header and Validation

In the code that handles incoming REST requests, validate the Kahuna request by checking the request's signature:

  1. Create a string that contains a concatenation of all the email addresses in the payload, in alphabetical order, with no separator characters. Incoming Request Body describes the format of the incoming request payload.
  2. Generate a keyed-hash message authentication code (HMAC) using the SHA1 cryptographic hash function (see the Wikipedia article Hash based message authentication code. For a key, use your namespace API Key.

    The API Key for the namespace is Available in Settings.

    The result is a binary signature.

  3. Encode this binary signature in Base64 (see the Wikipedia article Base64.
  4. Compare the Base64-encoded value to the value in the X-Kahuna-Signature HTTP request header.
Incoming HTTP Request Headers

The following list describes the HTTP request headers:

Content-Type: application/json

Accept-Charset: UTF-8

Validation: The HTTP Header X-Kahuna-Signature provides a validation signature.

Incoming Request Body

The incoming request body contains information about email errors Kahuna received when it ran your campaigns.

The format of the request body is an array of dictionaries. Each dictionary contains a reason, an email address, and a timestamp. A dictionary can optionally contain an expiration date.

reason Required. One of the following:
  • unsub—the recipient clicked on the unsubscribe link in an email.
  • hard_bounce—a permanent error occurred during transmission. For example, the domain of the email address no longer exists.
  • soft_bounce—a temporary error occurred. Kahuna waits for a time, then attempts to resend the email. Temporary errors can occur, for example, when the user's inbox is full.
  • spam—the recipient reported the email as spam.
  • rejectKahuna rejected the email address as it was creating the campaign. Kahuna had received previous notification that the user name was invalid, or had received a previous unsub, bounce, or spam error.
email Required. The email address.

Required. The time of the error, in seconds since the Unix epoch. The date and time are GMT, rather than local.


Optional. A timestamp, in seconds since the Unix epoch, when the email address will be eligible for messaging again. The date and time are GMT, rather than local.

Note: For soft bounces, Kahuna waits 7 to 14 days before trying to send to the address again. For hard bounces, Kahuna waits 80 to 100 days. The exact day is randomized to spread out the outgoing email load and avoid harming your user reputation in the mail system Kahuna uses.


The following is an incoming request.

        "email": "",
        "reason": "unsub",
        "timestamp": 1476547200
        "email": "", 
        "reason": "hard_bounce",
        "timestamp": 1477605600,
        "expiration": 1477605600

API Response

Respond to incoming requests with one of the following three HTTP status codes:


You received and validated the request. If you do not respond with this value within one minute, Kahuna re-sends the request and includes any additional errors it has received.

When you return this code, you are certifying that you received the request and validated its signature.

401 You received the request, but you were unable to validate the signature.
500 You encountered an internal error.
Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request