IntegrationsOtherBuild Your Own

Build Your Own Integration

Datafly Signal can deliver events to any HTTP API endpoint. If Signal doesn’t have a dedicated integration for your vendor, you can build your own using the Custom Integration builder or the webhook integration.

When to Use This

  • Connecting to an internal API or microservice
  • Sending events to a vendor not in Signal’s integration catalog
  • Custom data pipeline or ETL endpoint
  • Third-party CRM, ESP, or analytics tool with an HTTP API

Two Approaches

1. Custom Webhook (Simple)

Best for: Quick setup, simple endpoints, any HTTP API

The Custom Webhook integration lets you send events to any URL with configurable authentication, headers, payload format, and batching. It supports:

  • 4 authentication methods: None, Bearer Token, Basic Auth, HMAC Signature
  • Custom payload templates: Transform events into any JSON structure using Handlebars
  • Batching: Accumulate events and send in bulk
  • Rate limiting: Control request throughput

See the Custom Webhook documentation for full details.

2. Delivery Spec (Advanced)

Best for: Complex APIs with specific authentication flows, field mapping, response parsing

A Delivery Spec is a declarative definition of how to deliver events to an HTTP API. It covers:

  • Endpoint: URL with template variables, query parameters, HTTP method
  • Authentication: Bearer token, Basic Auth, API key (header or query), OAuth 2.0 (client credentials, refresh token, service account)
  • Payload: JSON or form-encoded body with field mappings, event wrappers, nested objects
  • Headers: Static and dynamic headers (e.g. forwarding IP/User-Agent)
  • Request signing: HMAC-SHA256/SHA1/SHA512 signatures
  • Batching: Event accumulation with configurable max size, wait time, and byte limits
  • Rate limiting: Token bucket rate limiter with configurable RPS and burst
  • Response handling: Status code classification, error body parsing

Delivery Specs are managed through the admin portal. If you need a custom Delivery Spec for a vendor, contact your Datafly account manager.

Setting Up a Custom Webhook

Step 1: Identify Your Endpoint

Gather the following from your target API documentation:

  • URL: The HTTP endpoint to send events to (must be HTTPS in production)
  • Method: Usually POST
  • Authentication: How the API authenticates requests
  • Payload format: What JSON structure the API expects
  • Rate limits: How many requests per second the API allows

Step 2: Choose an Authentication Method

MethodWhen to UseConfig Fields
NoneInternal endpoints, IP-allowlisted APIs
Bearer TokenMost REST APIs, API key authenticationauth_token
Basic AuthLegacy APIs, some enterprise servicesauth_username, auth_password
HMAC SignatureWebhook receivers, security-sensitive endpointshmac_secret, hmac_header

Step 3: Create the Integration

  1. In Signal, go to Integrations > Add Integration > Custom Webhook.
  2. Enter your endpoint URL.
  3. Select the authentication method and enter credentials.
  4. Choose the payload format:
    • Canonical: Sends the full Datafly event object as-is
    • Custom Template: Transform events using Handlebars syntax
  5. Configure batching if your API supports bulk requests.
  6. Set consent categories appropriate for the data being sent.
  7. Click Save.

Step 4: Map Your Payload (Optional)

If your API expects a specific JSON structure, use a custom Handlebars template:

{
  "config": {
    "payload_format": "custom",
    "payload_template": "{ \"event_type\": \"{{event}}\", \"user\": \"{{user_id}}\", \"data\": { \"page\": \"{{context.page.url}}\", \"revenue\": {{properties.total}} } }"
  }
}

Available template variables:

VariableDescription
{{event}}Event name (e.g. “Order Completed”)
{{type}}Event type (track, page, identify)
{{user_id}}User ID (if identified)
{{anonymous_id}}Anonymous visitor ID
{{timestamp}}ISO 8601 timestamp
{{context.page.url}}Current page URL
{{context.page.title}}Page title
{{context.ip}}Visitor IP address
{{context.user_agent}}Browser user agent
{{properties.*}}Any event property
{{traits.*}}Any user trait

Step 5: Test the Integration

  1. Enable the integration and trigger some events on your website.
  2. Check the Integration Detail page in Signal for delivery status.
  3. Verify events are arriving at your endpoint.

HMAC Verification

If you’re building a receiving endpoint, here’s how to verify HMAC signatures:

Node.js:

const crypto = require('crypto');
 
function verifySignature(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
 
// In your Express handler:
app.post('/events', (req, res) => {
  const sig = req.headers['x-signature-256'];
  if (!verifySignature(JSON.stringify(req.body), sig, process.env.HMAC_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  // Process event...
  res.json({ ok: true });
});

Python:

import hmac
import hashlib
 
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Go:

func verifySignature(body []byte, signature, secret string) bool {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write(body)
    expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
    return hmac.Equal([]byte(signature), []byte(expected))
}

Batching Configuration

For high-volume endpoints, enable batching to reduce the number of HTTP requests:

{
  "config": {
    "batch_enabled": true,
    "batch_size": 100,
    "batch_interval_ms": 5000
  }
}

Events are buffered and sent as a JSON array when either:

  • The buffer reaches batch_size events, or
  • batch_interval_ms milliseconds have elapsed since the first buffered event

Troubleshooting

ProblemSolution
401/403 errorsCheck authentication credentials. Ensure the token/password hasn’t expired.
400 Bad RequestThe payload format doesn’t match what the API expects. Use a custom template.
Timeout errorsIncrease timeout_ms or check that the endpoint is reachable.
Events not arrivingVerify the URL is correct and the endpoint is publicly accessible (or on the same network).
Duplicate eventsEnable event deduplication on your receiving endpoint using the event_id field.
Rate limit errors (429)Reduce rate_limit_rps in the integration config to match your API’s limits.