Attribution Webhooks

Create webhook subscription

Changed on

Creates a new webhook subscription for this campaign. When attributed investments change state, we'll POST a JSON payload to your target URL.

Tier 1 endpoint requiring admin-approved access.

Webhook Payload

Payloads include anonymized data (tokens, amount tiers) matching the /attribution/investments endpoint.

Security

  • target_url must use HTTPS
  • target_url cannot resolve to private/internal IPs (SSRF protection)
  • Payloads are signed with HMAC-SHA256 using the returned secret

Verification

Verify webhook signatures using the X-Wefunder-Signature header:

timestamp = headers['X-Wefunder-Timestamp']
signature = headers['X-Wefunder-Signature']
expected = "sha256=" + HMAC-SHA256(secret, timestamp + "." + raw_body)

Reject requests where:

  • Signature doesn't match
  • Timestamp is more than 5 minutes old (replay protection)
post/campaigns/{campaign_id}/attribution/webhooks

Request

  • Base URL: https://api.wefunder.com
  • URL: https://api.wefunder.com/campaigns/{campaign_id}/attribution/webhooks
  • Auth: OAuth 2 (authorization code, authorization URL https://wefunder.com/oauth/authorize, token URL https://api.wefunder.com/oauth/token; client credentials, token URL https://api.wefunder.com/oauth/token, scopes: read:attribution:anonymized)

Path parameters

campaign_idinteger required

The fundraise/campaign ID

Request body

target_urlstring uri required

HTTPS URL to receive webhook POSTs

eventsstring[] required

Events to subscribe to

Example request

{
  "target_url": "https://yourapp.com/webhooks/wefunder",
  "events": [
    "investment.applied",
    "investment.confirmed"
  ]
}

Response

Subscription created

Example response

{
  "data": {
    "id": 123,
    "campaign_id": 789,
    "target_url": "https://yourapp.com/webhooks/wefunder",
    "events": [
      "investment.applied",
      "investment.confirmed"
    ],
    "active": true,
    "created_at": "2025-03-15T10:30:00Z",
    "updated_at": "2025-03-15T10:30:00Z",
    "secret": "whsec_a1b2c3d4e5f6g7h8i9j0..."
  }
}

Changes

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status