PruuvDocs

Webhook API

If you prefer to send conversion events from your server rather than the browser, you can POST directly to the Pruuv webhook endpoint. This is useful when you already have lead data in a CRM or backend system and want to forward it to Pruuv without adding JavaScript to your pages.

Important: Server-side integrations cannot automatically capture fbc / fbp (Meta cookies) or ttclid (TikTok click ID) — these can only be read from the browser at the moment of the ad click. For best Meta and TikTok match rates, use the Pixel SDK on your landing pages and include the cookie values in your server-side payload.

Authentication

All requests must include a Bearer token in the Authorization header. The token is the Webhook Token shown alongside each funnel stage in Connections > Funnel Webhooks.

Endpoint

bash
POST https://app.pruuv.io/api/webhooks/funnel/{stageId}
Authorization: Bearer YOUR_WEBHOOK_TOKEN
Content-Type: application/json

Example request

bash
curl -X POST https://app.pruuv.io/api/webhooks/funnel/YOUR_STAGE_ID \
  -H "Authorization: Bearer YOUR_WEBHOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reference":    "CRM-REF-001",
    "utm_source":   "google",
    "utm_medium":   "cpc",
    "utm_campaign": "brand-search",
    "gclid":        "EAIaIQobCh...",
    "revenue_value": 250,
    "currency":     "GBP"
  }'

Payload reference

All fields are optional except reference.

FieldTypeDescription
referencestringRequired. Unique identifier for this contact or conversion. Used for deduplication.
item_referencestringSecondary reference — deal ID, order number, etc.
utm_sourcestringUTM source parameter
utm_mediumstringUTM medium parameter
utm_campaignstringUTM campaign parameter
utm_contentstringUTM content parameter (used for ad-level attribution)
utm_termstringUTM term parameter
gclidstringGoogle click ID
wbraidstringGoogle web-to-app click ID
gbraidstringGoogle app-to-web click ID
ttclidstringTikTok click ID
msclkidstringMicrosoft/Bing click ID
fbcstringMeta _fbc cookie value
fbpstringMeta _fbp cookie value
click_timestampISO datetimeTime of the original ad click (required for Google Conversion Upload API)
revenue_valuenumberConversion value
currencystringISO 4217 currency code (e.g. GBP, USD, EUR)
data_timestampISO datetimeConversion timestamp. Defaults to now if omitted.
genderstringDemographic — for reporting only
age_rangestringDemographic — for reporting only
location_countrystringDemographic — for reporting only
location_regionstringDemographic — for reporting only
job_titlestringDemographic — for reporting only
company_sizestringDemographic — for reporting only
industrystringDemographic — for reporting only

Responses

StatusBodyMeaning
200{ received: true, event_id: "..." }Event accepted and stored
200{ received: true, duplicate: true }Duplicate — same reference at same stage within 60 seconds
400{ error: "Validation failed", details: {...} }Invalid payload — check field types
401{ error: "Unauthorized" }Missing or incorrect bearer token
404{ error: "Stage not found" }stageId does not exist
429{ error: "Rate limit exceeded" }More than 1,000 events/hour for this stage
500{ error: "Internal error" }Server error — contact support if persistent

Deduplication

Events with the same reference at the same stage within a 60-second window are deduplicated. Only the first call is recorded; subsequent identical calls within the window return { received: true, duplicate: true } with a 200 status. This makes it safe to retry on network errors.

Rate limits

The webhook accepts a maximum of 1,000 events per hour per funnel stage. Requests beyond this limit receive a 429 response.

Integration paths compared

PathGoogle (gclid)Meta (fbc/fbp)TikTok (ttclid)Effort
Pruuv Pixel (recommended)Auto-capturedAuto-capturedAuto-capturedPaste snippet + call track()
Backend webhookMust capture yourself (hidden field)Requires JS on landing pageRequires JS on landing pageSelf-implement capture + POST
CRM pull (coming soon)Available if CRM stores gclidRarely stored in CRMsRarely stored in CRMsCRM config only