Skip to content

Events

POST /attribution/events

Records a conversion event. The authoritative source for revenue + funnel state changes — emit from your server (or a CRM webhook), not the browser.

Auth: Admin API key OR scoped key with events:write.

Request

POST <base>/attribution/events
Authorization: Bearer <key>
Content-Type: application/json
{
"userId": "user_abc",
"type": "invoice_paid",
"value": 49.00,
"currency": "USD",
"metadata": { "stripe_invoice_id": "in_12345" },
"ts": "2026-04-24T12:00:00Z"
}
FieldTypeRequiredNotes
userIdstringyesSame identifier you assigned at signup time so OpenPartner can stitch the event to a click.
typestringyesStandard or custom event name. Conventions: signup, trial_started, subscription_created, invoice_paid, opportunity_won, trial_converted.
valuenumberconditionalRequired for events that drive percent commissions. Decimal in major units (dollars, not cents).
currencystringconditionalISO 4217. Defaults to USD when value is set.
metadataobjectnoFree-form. Stored on the Event row; surfaced in attribution + webhook payloads.
tsstringnoISO 8601 timestamp. Defaults to server time. Set this when forwarding async events to preserve attribution-window math.

Response

{
"ok": true,
"eventId": "01HXX...",
"attribution": {
"status": "attributed",
"model": "last_click",
"touches": [
{
"clickId": "01HXX...",
"partnerId": "01HXX...",
"weight": 1,
"attributionId": "01HXX...",
"commissionId": "01HXX..."
}
]
}
}

attribution.status is one of:

  • attributed — at least one click stitched to this user’s identity, attribution + commission rows written
  • no_clicks — no clicks tied to this user; event recorded but unattributed
  • already_attributed — duplicate event (same userId + type + close ts)

Common patterns

HubSpot Workflows / Zapier / Make: wire your CRM’s “deal stage = closed_won” trigger to POST here with type: 'opportunity_won'. See CRM integration for the full setup walkthrough.

Stripe webhooks: if your billing system is Stripe, subscribe to invoice.paid and POST here with type: 'invoice_paid' + the customer’s userId. Or use the OpenPartner SDK to emit directly from your server-side checkout handler.

Idempotency

Pass Idempotency-Key: <unique> to make event creation safe to retry. The same key returns the original event without creating a duplicate. Useful when re-firing CRM webhooks.