Webhook API

Webhook API

Send server-side events from any platform. CRM, ERP, mobile apps, POS systems, or any custom integration.

OVERVIEW

Introduction

The Webhook API lets you send server-side events to Dnomia from any platform. Events are processed through the same pipeline as client-side SDK events: enrichment, profile matching, and forwarding to your configured destinations.

1
No SDK required. Standard HTTP POST with JSON body.
2
Events are processed in real-time through Inngest pipelines.
3
Same destination routing as SDK events (Meta CAPI, Google Ads, Klaviyo, etc.).
4
Custom source naming for organizing events by origin.
SECURITY

Authentication

All webhook requests must include your store's secret key as a Bearer token in the Authorization header.

Authorization Header
Authorization: Bearer sk_live_YOUR_SECRET_KEY

Find your secret key in Dashboard > Store Settings > API Keys. Never expose your secret key in client-side code.

API

Endpoint

Send events to the webhook endpoint with your chosen source name in the URL path.

Webhook Endpoint
POST https://scout.dnomia.app/v1/webhook/{source}

Content-Type: application/json
Authorization: Bearer sk_live_YOUR_SECRET_KEY
/v1/webhook/crmCRM system events
/v1/webhook/erpERP integration events
/v1/webhook/mobile-appMobile application events
/v1/webhook/posPoint of sale events
SCHEMA

Payload Format

The JSON body follows the GenericWebhookPayload schema. Only the 'event' field is required.

GenericWebhookPayload
{
  "event": "Placed Order",        // Required. Event name.
  "event_id": "evt_abc123",       // Optional. Dedup key. Auto-generated if missing.
  "properties": {
    "order_id": "ORD-12345",      // Optional. Order identifier.
    "value": 299.90,              // Optional. Monetary value.
    "discount": 50.00,            // Optional. Discount amount.
    "currency": "TRY",            // Optional. Default: "TRY".
    "items": [                    // Optional. Line items.
      {
        "item_id": "SKU-001",     // Required (in items).
        "item_name": "Product",   // Required (in items).
        "item_category": "Shoes", // Optional.
        "item_brand": "Nike",     // Optional.
        "price": 149.95,          // Required (in items).
        "discount": 25.00,        // Optional.
        "quantity": 2             // Required (in items).
      }
    ],
    "custom_field": "any value"   // Custom properties pass through.
  },
  "user": {
    "email": "user@example.com",  // At least one identifier recommended.
    "phone": "+905551234567",
    "external_id": "usr_123",
    "first_name": "Ahmet",
    "last_name": "Yilmaz"
  }
}
eventRequired. The event name (e.g., "Placed Order", "Signed Up"). Used for routing and analytics.
event_idOptional. Deduplication key. If omitted, a UUID is auto-generated. Use this to prevent duplicate processing.
propertiesOptional. Event properties. Standard e-commerce fields (value, currency, items) are recognized. Custom properties pass through.
userOptional. User identification. At least one identifier (email, phone, external_id) is recommended for profile matching.
EVENTS

Event Types

You can send any event name. These are commonly used events that have special handling in destinations.

Placed OrderPurchase completed. Include value, currency, items, and order_id.
Started CheckoutCheckout initiated. Include value and currency.
Added to CartItem added to cart. Include items array.
Signed UpNew user registration. Include user email/phone.
Viewed ProductProduct page view. Include item details.
IDENTITY

User Data

User fields are used for profile matching and destination enrichment. PII (email, phone) is hashed before forwarding to ad platforms.

emailEmail address. SHA-256 hashed before sending to Meta CAPI, Google Ads, etc.
phonePhone number (E.164 format recommended). Hashed for ad platform destinations.
external_idYour internal user ID. Used for cross-platform profile matching.
first_nameFirst name. Hashed for ad platform enhanced matching.
last_nameLast name. Hashed for ad platform enhanced matching.
ERRORS

Error Handling

The API returns standard HTTP status codes. Implement retry logic for 5xx errors.

Response Codes
// 200 OK - Success
{ "success": true, "eventsReceived": 1 }

// 401 Unauthorized - Invalid or missing Bearer token
{ "error": "Unauthorized" }

// 400 Bad Request - Missing required "event" field
{ "error": "Invalid payload" }

// 429 Too Many Requests - Rate limit exceeded
{ "error": "Rate limit exceeded" }
LIMITS

Rate Limits

1,000

requests per minute per store

1 MB

maximum request body size

CODE

Examples

curl

curl
curl -X POST "https://scout.dnomia.app/v1/webhook/my-source" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
  -d '{
    "event": "Placed Order",
    "properties": {
      "order_id": "ORD-12345",
      "value": 299.90,
      "currency": "TRY",
      "items": [{
        "item_id": "SKU-001",
        "item_name": "Product Name",
        "price": 149.95,
        "quantity": 2
      }]
    },
    "user": {
      "email": "customer@example.com",
      "phone": "+905551234567"
    }
  }'

JavaScript (fetch)

JavaScript
const response = await fetch(
  "https://scout.dnomia.app/v1/webhook/my-source",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer sk_live_YOUR_SECRET_KEY",
    },
    body: JSON.stringify({
      event: "Placed Order",
      properties: {
        order_id: "ORD-12345",
        value: 299.90,
        currency: "TRY",
        items: [{
          item_id: "SKU-001",
          item_name: "Product Name",
          price: 149.95,
          quantity: 2,
        }],
      },
      user: {
        email: "customer@example.com",
      },
    }),
  }
);

const result = await response.json();
console.log(result);

Python (requests)

Python
import requests

response = requests.post(
    "https://scout.dnomia.app/v1/webhook/my-source",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer sk_live_YOUR_SECRET_KEY",
    },
    json={
        "event": "Placed Order",
        "properties": {
            "order_id": "ORD-12345",
            "value": 299.90,
            "currency": "TRY",
            "items": [{
                "item_id": "SKU-001",
                "item_name": "Product Name",
                "price": 149.95,
                "quantity": 2,
            }],
        },
        "user": {
            "email": "customer@example.com",
        },
    },
)

print(response.json())