RecomlyRecomlyRecomlyDocs
Integrations

Inbound Webhooks

Send signed HTTP requests to Recomly to enroll advocates automatically from your existing systems.

Inbound webhooks let your CRM, booking system, or any custom application enroll advocates into a Recomly campaign by sending a single HTTP request. There is no polling, no manual data entry, and no Zapier required.

Inbound webhooks require the Integrations feature entitlement. Org admins can manage signing keys under Integrations → Webhooks in the dashboard.

Endpoints

MethodEndpointDescription
POSThttps://api.recomly.com/api/public/webhook/inviteEnroll advocates

Authentication

Every request must be authenticated with a signing key. Signing keys are created in the dashboard under Integrations → Webhooks. Each key has a unique key ID and a signing secret.

The signing secret is shown exactly once when the key is created. Store it securely — it cannot be retrieved after the creation dialog is closed.

Request headers

HeaderValue
Content-Typeapplication/json
X-Recomly-Key-IdYour key ID
X-Recomly-SignatureHMAC-SHA256 signature (see below)

Signature format

The X-Recomly-Signature header must be formatted as:

t=<unix_timestamp>,v1=<hmac_hex>

Where:

  • <unix_timestamp> is the current Unix timestamp in seconds (e.g. 1712345678)
  • <hmac_hex> is an HMAC-SHA256 hex digest computed over the string <unix_timestamp>.<raw_request_body>, using your signing secret as the key

Recomly validates the signature and rejects requests with a timestamp older than 5 minutes to prevent replay attacks.


Payload reference

The request body must be a JSON object with the following fields:

FieldTypeRequiredDescription
campaignIdstringYesID of the active campaign to enroll the advocate into
namestringYesFull name of the advocate (1–200 characters)
emailstringOne ofEmail address. At least one of email or phone must be provided.
phonestringOne ofE.164 phone number (e.g. +15551234567). Required if email is omitted.

Response

All requests return 200 { "ok": true }, including requests with an invalid key or bad signature — this is intentional and prevents key enumeration. If advocates aren't appearing after a successful send, double-check that the Key ID and signing secret match what's shown in the dashboard under Integrations → Webhooks.

StatusMeaning
200Request accepted
400Invalid request body — malformed JSON or missing required fields
500Internal server error

Code examples

curl

curl -X POST https://api.recomly.com/api/public/webhook/invite \
  -H "Content-Type: application/json" \
  -H "X-Recomly-Key-Id: YOUR_KEY_ID" \
  -H "X-Recomly-Signature: t=$(date +%s),v1=$(echo -n "$(date +%s).BODY" | openssl dgst -sha256 -hmac YOUR_SECRET | awk '{print $2}')" \
  -d '{"campaignId":"CAMPAIGN_ID","name":"Jane Smith","email":"jane@example.com"}'

Node.js

import crypto from 'crypto';

const KEY_ID  = process.env.RECOMLY_KEY_ID;
const SECRET  = process.env.RECOMLY_SIGNING_SECRET;
const ENDPOINT = 'https://api.recomly.com/api/public/webhook/invite';

async function enrollAdvocate(payload) {
  const body = JSON.stringify(payload);
  const ts   = Math.floor(Date.now() / 1000);
  const sig  = crypto.createHmac('sha256', SECRET)
                     .update(`${ts}.${body}`)
                     .digest('hex');
  const res = await fetch(ENDPOINT, {
    method:  'POST',
    headers: {
      'Content-Type':         'application/json',
      'X-Recomly-Key-Id':    KEY_ID,
      'X-Recomly-Signature': `t=${ts},v1=${sig}`,
    },
    body,
  });
  return res.json();
}

// Example
await enrollAdvocate({
  campaignId: 'CAMPAIGN_ID',
  name:       'Jane Smith',
  email:      'jane@example.com',
  phone:      '+15551234567',   // optional
});

Python

import hmac, hashlib, time, json, os, urllib.request

KEY_ID   = os.getenv('RECOMLY_KEY_ID')
SECRET   = os.getenv('RECOMLY_SIGNING_SECRET').encode()
ENDPOINT = 'https://api.recomly.com/api/public/webhook/invite'

def enroll_advocate(payload: dict):
    body = json.dumps(payload).encode()
    ts   = str(int(time.time()))
    sig  = hmac.new(SECRET, f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
    req  = urllib.request.Request(
        ENDPOINT,
        data    = body,
        method  = 'POST',
        headers = {
            'Content-Type':         'application/json',
            'X-Recomly-Key-Id':    KEY_ID,
            'X-Recomly-Signature': f't={ts},v1={sig}',
        },
    )
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read())

# Example
enroll_advocate({
    'campaignId': 'CAMPAIGN_ID',
    'name':       'Jane Smith',
    'email':      'jane@example.com',
})

On this page

We use cookies

We use essential cookies to keep the site working, and optional analytics cookies to understand how it's used. Read our Privacy Policy.