Webhooks

The Tremendous API supports a callback system allowing you to react to the various events that happen within your organization's account.

The system uses webhooks to send notifications to one of your servers over HTTPS.

List of available events

Webhook eventDescription
CAMPAIGNS.CREATEDA campaign is created in the UI.
CAMPAIGNS.DELETEDA campaign is deleted in the UI.
CONNECTED_ORGANIZATIONS.DELETEDA connected organization was deleted, either via the API or by the end client through their Integrations page. The customer’s Tremendous organization is not deleted, and they can still access it from tremendous.com.
CONNECTED_ORGANIZATIONS.REGISTEREDA user has finished onboarding their organization through the Tremendous Connect integration.
CONNECTED_ORGANIZATIONS.STATUS.APPROVEDA connected organization was approved by Tremendous’s compliance team.
CONNECTED_ORGANIZATIONS.STATUS.REJECTEDA connected organization was rejected by Tremendous’s compliance team.
CONNECTED_ORGANIZATIONS.OAUTH.GRANTEDAn OAuth token has been granted for the connected organization. Use this token to fetch the first access and refresh tokens for this organization.
CONNECTED_ORGANIZATION_MEMBERS.DELETEDA member was removed from a connected organization via the API.
FUNDING_SOURCES.CREATEDA funding source, like a credit card or a bank account, has been added.
FUNDING_SOURCES.DELETEDA funding source has been removed.
FUNDING_SOURCES.FUNDEDYour Tremendous balance has had funds added and made available.
INVOICES.CREATEDAn invoice was created.
INVOICES.DELETEDAn invoice was deleted.
INVOICES.PAIDAn invoice has been paid.
MEMBERS.CREATEDA user was added to the team.
MEMBERS.DELETEDA user was removed from your team.
ORDERS.APPROVED

Your order was approved by an admin.

This webhook will only fire if order approvals are on.

ORDERS.CANCELEDAn order was rejected by you after it was held for review.
ORDERS.CREATEDAn order was created.
ORDERS.FAILED

Your order failed. This typically happens if a credit card was declined.

This never happens for API orders where there is a single reward per order. Those requests are processed synchronously, and error codes are returned if there's an issue.

PRODUCTS.ADDEDA product was added to the Tremendous product catalog, and made available.
PRODUCTS.REMOVEDA product was removed from the Tremendous product catalog, and is no longer available.
PRODUCTS.UPDATEDA product in the Tremendous product catalog was updated. Typically, this relates to changes in the available denominations.
REWARDS.CANCELEDA reward was canceled; this can happen for a variety of reasons.
REWARDS.FLAGGEDA reward is flagged for fraud review.
REWARDS.DELIVERY.FAILED

The reward delivery failed, usually due to an email bounce.

This does not apply to LINK rewards.

See Reward delivery failed for details on the metadata returned.

REWARDS.DELIVERY.SUCCEEDED

Tremendous received confirmation that the reward email was delivered to the end-user.

This does not apply to LINK rewards.

FRAUD_REVIEWS.RELEASEDA reward is released after fraud review.
FRAUD_REVIEWS.BLOCKEDA reward is blocked after fraud review.
REPORTS.GENERATION.SUCCEEDEDA report has successfully finished generating and is ready for download.
REPORTS.GENERATION.FAILEDA report failed to generate.
TOPUPS.CREATEDThe topup is processing (and may be under review).
TOPUPS.FULLY_CREDITEDThe funds have been added to the balance.
TOPUPS.PARTIALLY_CREDITEDSome funds from the topup have been added to the balance. The remainder is pending settlement.
TOPUPS.REVERSEDThe topup was credited, but then reversed due to a chargeback or ACH return.
TOPUPS.REJECTEDThe topup was rejected by an admin.

Webhook setup

Every organization can set up a single endpoint to where we will send webhook requests. You can configure that receiving endpoint (e.g. its URL) via the API. See the API reference for the webhook endpoints.

📘

The configured receiver will be notified about every event that occurs within your account. You cannot pre-select which events get sent, but you can filter events on the receiver according to your needs.

Webhook requests

Webhooks will be sent as HTTP POST requests. The request body is a JSON document that looks like this:

{
  "event": "CAMPAIGNS.CREATED",
  "uuid": "5ccc7bb1-7659-4e23-a407-77d8cd9c62f5",
  "created_utc": "2021-04-06T20:05:01.037-04:00",
  "payload": {
    "resource": {
      "id": "2V3PCCL7QXDA",
      "type": "campaigns"
    },
    "meta": {
    }
  }
}

Request properties

PropertyDescription
event

Type of the event (see

list of events

)

uuid

Unique ID of the webhook itself (can be used to avoid executing the same webhook twice / see

Responding to Webhooks / Errors & Retries

)

created_utcTimestamp when the event happened
payloadDetails on the event and it's context (the other top-level properties describe meta information about the event)
payload.resourceDescribes the main resource this event is referring to (e.g. a specific campaign for the CAMPAIGNS.CREATED event)
payload.resource.idTremendous ID of the resource (can be used to obtain details about the resource through a separate API call)
payload.resource.type

What kind of resource this event is referring to. Possible values:

campaigns
funding_sources
invoices
members
orders
organizations
payments
products
rewards

payload.metaCurrently, most events don't use this field (returning an empty object ({})), except for:
  • ORDERS.CREATED - returns the created Order schema
  • REWARDS.DELIVERY.FAILED - see Reward delivery failed for schema

Responding to webhooks / errors & retries

The endpoint that receives webhooks from our system must respond with a 200 HTTP response code. If it fails to do so, the same webhook will be retried up to 17 times, with an exponential delay (backoff) between attempts.

Please make sure to check the webhook's uuid field on every webhook to ensure you are not reacting to the same event multiple times.

📘

We recommend setting up your webhook endpoint such that it processes webhooks asynchronously, out of the request/response loop (e.g. a worker queue). This ensures that Tremendous gets a timely response and thus won't retry the webhook request.

Webhook IPs

All webhook requests are originated from the following IP addresses:

# Production
34.150.143.187
34.86.45.235
35.188.236.188
34.150.208.194

# Sandbox
35.194.78.88
34.150.132.8
34.145.182.28
35.221.12.21

Webhook verification

To verify that the webhook sent to your receiver originates from Tremendous, every request is signed. You can find the signature in a HTTP request header named Tremendous-Webhook-Signature. The header's value is always a prefix (sha256=), followed by the actual signature.

The signature is signing the whole request body using HMAC-SHA256 in a hexadecimal representation.

You can obtain the private key used for the signature during the configuration of your webhook endpoint. It will be returned in the API response when you create the webhook or when you retrieve a webhook through the API.

📘

When attempting to verify the webhook signature, be sure to use the raw request body as an input. Any changes to the request body (e.g. calling JSON.stringify) may result in a different payload, and as such the expected signature will be different.

Verification example (Ruby):

def request_valid?(private_key:, request:)
  signature_header = request.headers['Tremendous-Webhook-Signature']
  algorithm, received_signature = signature_header.split('=', 2)

  expected_signature = OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest.new('sha256'), private_key, request.body.read
  )

  received_signature == expected_signature
end

Multiple webhook receiver

If you need to receive webhooks to multiple endpoints:

  1. Setup a central receiving endpoint on your side
  2. Let that receiver fan out notifications to other parts of your infrastructure