Contact Support

Send events from your backend systems, CRM, or automation platforms (Zapier, Make, n8n) directly to inPIPE for processing and forwarding to your connected platforms (Google Analytics 4, Facebook Ads, etc.).

Quick Start #

1. Enable Custom Webhook #

  1. Go to inPIPE > Connections in your WordPress admin
  2. Click Configure on the Custom Webhook card
  3. Toggle Enable Custom Webhook to ON
  4. Copy your API Key and Endpoint URL

2. Send Your First Event #

curl -X POST "https://yoursite.com/wp-json/inpipe/v1/webhook/events" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"event_name":"purchase","event_id":"order_12345","timestamp":1706918400,"webhook_source":"my_backend","value":99.99,"currency":"USD"}'

3. Verify #

Check the Tracked Events page in inPIPE admin to see your event with source custom_webhook.

Authentication #

Include your API key in the X-API-Key header:

POST /wp-json/inpipe/v1/webhook/events
Content-Type: application/json
X-API-Key: cwh_your_api_key_here

All requests must use HTTPS. Store your API key securely – use environment variables or a secrets manager, never hardcode it.

Event Payload #

Required Fields #

FieldTypeDescriptionExample
event_namestringWhat happened"purchase", "signup"
event_idstringUnique identifier"order_12345"
timestampintegerUnix timestamp in seconds1706918400

Timestamp Format #

LanguageCode
JavaScriptMath.floor(Date.now() / 1000)
Pythonint(time.time())
PHPtime()

Common mistake: JavaScript Date.now() returns milliseconds. Always divide by 1000.

Common Fields #

webhook_source (Recommended) #

Identifies the source system sending the event. Used for filtering and analytics in BigQuery.

ScenarioValue
You send webhook_sourceYour value (e.g., "salesforce", "hubspot", "zapier")
You do NOT send itFallback: "unknown-{api_key_id}" (e.g., "unknown-cwh_25959523")

Note: webhook_source and items are pass-through fields – they are NOT stripped as reserved fields.

Other Common Fields #

FieldTypeDescription
user_idstringYour internal user ID
emailstringUser email (SHA-256 hash recommended)
client_idstringGA4 client ID (if available)
valuenumberMonetary value
currencystringISO currency code (USD, EUR)
transaction_idstringOrder/transaction ID

Platform Click IDs #

FieldDescription
gclidGoogle Click ID
fbclidFacebook Click ID
fbcFacebook Cookie (_fbc)
fbpFacebook Pixel (_fbp)
ttclidTikTok Click ID
msclkidMicrosoft/Bing Click ID

UTM Parameters #

utm_source, utm_medium, utm_campaign, utm_term, utm_content

User Data (for Conversion APIs) #

email, phone, first_name, last_name, city, state, country, zip

Custom Fields #

Any field not in the standard fields list is treated as a custom field and stored in BigQuery.

Limits #

Custom Fields SentBehavior
1-30All accepted and stored
31-100First 30 accepted, extras stripped (logged server-side)
>100Rejected with 413 error: “Custom fields payload too large”

Standard fields (not counted as custom): event_name, event_id, timestamp, webhook_source, user_id, email, client_id, value, currency, transaction_id, user_agent, fbc, fbp, fbclid, gclid, ttclid, msclkid, phone, first_name, last_name, city, state, country, zip, utm_source, utm_medium, utm_campaign, utm_term, utm_content, items.

Querying Custom Fields in BigQuery #

SELECT JSON_VALUE(custom_fields, "$.webinar_id") as webinar_id
FROM outpipe_events
WHERE webhook_source = "hubspot"

Items Array (E-commerce) #

For purchase, add_to_cart, and other e-commerce events. Max 30 items per event.

FieldRequiredDescription
item_idYesProduct SKU or ID
item_nameYesProduct name
priceNoUnit price
quantityNoQuantity (default: 1)
item_categoryNoProduct category
item_brandNoBrand name

Standard Events #

Event NameGA4Facebook
page_viewpage_viewPageView
purchasepurchasePurchase
add_to_cartadd_to_cartAddToCart
begin_checkoutbegin_checkoutInitiateCheckout
generate_leadgenerate_leadLead
signupsign_upCompleteRegistration
view_itemview_itemViewContent

Error Handling #

Response Codes #

CodeError CodeMeaning
202Event queued successfully
400validation_errorCheck payload format
401invalid_api_keyCheck API key
403webhook_disabledWebhook is disabled
409duplicate_eventSame event_id sent within 24 hours
413payload_too_largePayload exceeds 10 KB
413custom_fields_too_largeMore than 100 custom fields sent
429rate_limit_exceededRate limit hit (60/min, 500/hr, 5000/day)
429quota_exceededMonthly event quota exhausted
500queue_errorServer error – retry with backoff

Rate Limits #

LimitValue
Per minute60 requests
Per hour500 requests
Per 24 hours5,000 requests
Payload size10 KB max
Custom fields30 max (31-100 stripped, >100 rejected)
Items array30 items max

Rate Limit Headers #

X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 42
X-RateLimit-Limit-Hour: 500
X-RateLimit-Remaining-Hour: 380
X-RateLimit-Limit-Day: 5000
X-RateLimit-Remaining-Day: 4200
X-RateLimit-Reset: 1706918460

Test Mode #

Validate payload without queuing:

curl -X POST "https://yoursite.com/wp-json/inpipe/v1/webhook/events" \
  -H "X-API-Key: cwh_your_api_key" \
  -H "X-Test-Mode: true" \
  -d '{"event_name":"test","event_id":"test_123","timestamp":1706918400}'

Code Examples #

Node.js #

const response = await fetch(ENDPOINT, {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    body: JSON.stringify({
        event_name: "purchase",
        event_id: `order_${Date.now()}`,
        timestamp: Math.floor(Date.now() / 1000),
        webhook_source: "my_app",
        value: 99.99,
        currency: "USD"
    })
});

Python #

import requests, time
response = requests.post(
    ENDPOINT,
    headers={"Content-Type": "application/json", "X-API-Key": API_KEY},
    json={
        "event_name": "purchase",
        "event_id": f"order_{int(time.time())}",
        "timestamp": int(time.time()),
        "webhook_source": "my_app",
        "value": 99.99,
        "currency": "USD"
    }
)

PHP #

$ch = curl_init($endpoint);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode([
        "event_name" => "purchase",
        "event_id" => "order_" . time(),
        "timestamp" => time(),
        "webhook_source" => "my_app",
        "value" => 99.99,
        "currency" => "USD"
    ]),
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: " . $apiKey
    ],
    CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);

Troubleshooting #

“401 Unauthorized” #

  • Check API key is correct
  • Ensure no extra whitespace in header
  • Verify key has not been regenerated

“409 Conflict” #

  • Same event_id sent within 24 hours
  • Use unique event IDs

“413 Custom fields payload too large” #

  • More than 100 custom fields sent
  • Reduce to 30 or fewer custom fields

“429 Rate limit exceeded” #

  • Check X-RateLimit-Remaining headers
  • Wait until X-RateLimit-Reset timestamp
  • Implement exponential backoff

“429 quota_exceeded” #

  • Monthly subscription quota exhausted
  • Contact admin to check event limits

Events not appearing #

  • Check Tracked Events page first (source: custom_webhook)
  • Verify outPIPE connections are active
  • Allow 5-15 minutes for processing
  • Include platform IDs (fbc, gclid, email) for attribution

Security Checklist #

  • API key in environment variable (not hardcoded)
  • HTTPS for all requests
  • Hash email/phone with SHA-256 (64-char lowercase hex)
  • Consistent identifiers across related events
  • Test mode validation before production

What are your feelings

Updated on February 5, 2026