Enabling Webhooks

📘

Webhooks are part of our Enterprise plans. Please contact us if you are interested in this feature.

What does Nami provide via Webhook?

Nami provides a variety of data generated by use of our platform that can be sent via webhook to your servers or a third-party platform.

See our list of webhooks event types for everything Nami supports.

The Webhook Payload

The webhook payload will always have the following fields:

  • created_date ISO 8601 format time field for when the event was created
  • event_type the hierarchial event type
  • id unique id for the event
  • user_id Nami's unique user ID associated with the event

Additional data will be available based on the event_type. Take a look at the event types guide for more details.

A full JSON schema for all event payloads is also available here.

📘

Receiving Only the Events you Want

We will be adding new functionality to allow you to subscribe to only the events you wish to receive in the Control Center soon.

For now, you can check the event_type when you process the events to only use the ones you need.

For example, maybe you want to process all user.subscription events or just user.subscription.purchased and user.subscription.cancelled events.

Sending of the Webhook

Nami sends events as a UTF-8 encoded JSON body with a header nami-signature that allows for validation.

Nami expects your application will return a 2xx status code upon a successful webhook receipt. If we receive any other status code, we will continue to retry sending the message. The retry logic has exponential backoff and some randomness. On average it will continue to retry once an hour for up to 24-hours before it stops trying to send a particular payload.

👍

Nami Best Practice

Because of the retry logic and the asynchronous nature of the sending of the webhooks there is no guarantee that you will receive each event in time order.

We recommend that you check the time stamp on the data you are receiving. In particular for user.subscription events, if you've received a more recent event, you can ignore the old one if all you need to know is your user's current subscription status.

Setting up the Webhook

🚧

Note that we are in the process of improving and expanding our capabilities for delivering data from Nami to you and any 3rd parties you would like to integrate with. While this work is underway, please contact support and provide the URL you would like us to send the webhook data to and we will get it set up for you.

Validation and Security

We provide a couple of options that you may use to both secure your webhook endpoint and validate that the data you are receiving is coming from Nami.

  1. Nami hashes the payload of all data sent with HMAC-SHA-256 and a shared secret that is available in our Control Center. The result of this hash is added as nami-signature to the header of the request. You can validate that the signature is correct on your end after receiving the data.

📘

Read here for more information on managing the Nami shared secret.

The following code sample can be used to receive a webhook, validate the signature, and respond to the webhook as either successful or failed.

from flask import Flask, request
import hashlib
import hmac
import os

NAMI_SIGNING_SECRET = bytes(os.environ["NAMI_SIGNING_SECRET"].encode("utf-8"))

app = Flask(__name__)


def compute_signature(data: bytes, secret: bytes) -> str:
  return hmac.new(
    key=secret,
    msg=data,
    digestmod=hashlib.sha256,
  ).hexdigest()


@app.route("/webhook", methods=["POST"])
def webhook():
  unverified_event = request.data
  received_nami_signature = request.headers.get("nami-signature")
  expected_signature = compute_signature(unverified_event, NAMI_SIGNING_SECRET)

  if not received_nami_signature:
    return ({"error": "nami-signature header not received."}, 400)

  if hmac.compare_digest(expected_signature, received_nami_signature):
    # Do Webhook Processing.
    validated_event = request.json
    print(validated_event)

    # Notify server the request succeeded
    return ("", 204)
  else:
    # Webhook fails validation, do not process the event.
    return (
      {
        "error": "Failed Signature Validation",
        "received": received_nami_signature,
        "expected": expected_signature,
      },
      400,
    )
  1. Nami webhooks come from a fixed IP address so you may explicitly allow traffic from our servers. You can retrieve the current list of IPs to add to your allow list from this endpoint and then look at the array for the key "webhook_outbound_ips".
https://api.namiml.com/allowlist.json

👍

Nami Best Practice

We recommend that you poll this endpoint on a regular basis and update your system with the latest list of outbound IPs for our webhooks. Once a day should be sufficient.


Did this page help you?