Skip to main content
When you import contacts with a webhook_url, Clustr sends a POST request to your URL once processing completes.

Payload format

The webhook payload contains the full results for all processed contacts:
{
  "status": "completed",
  "job_id": "job_abc123",
  "batch_id": "batch_xyz789",
  "summary": {
    "total_processed": 2,
    "total_opportunities": 15,
    "processing_time_seconds": 45.2
  },
  "results": [
    {
      "client": {
        "name": "John Doe",
        "first_name": "John",
        "last_name": "Doe",
        "linkedin_url": "https://www.linkedin.com/in/john-doe",
        "record_id": "CRM_12345",
        "owner_email": "alice@company.com",
        "job_title": "VP of Sales",
        "company_name": "Acme Corp"
      },
      "opportunities": [
        {
          "opportunity_id": "opp_abc123",
          "prospect": {
            "name": "Jane Smith",
            "linkedin_url": "https://www.linkedin.com/in/jane-smith",
            "job_title": "CTO",
            "company_name": "Target Inc"
          },
          "company": {
            "name": "Target Inc",
            "domain": "target-inc.com",
            "industry": "Technology",
            "employee_count": "501-1000"
          },
          "relationship": {
            "confidence_score": 85.5,
            "total_overlap_months": 24,
            "shared_experience": {
              "company_name": "Previous Corp",
              "overlap_months": 24,
              "client_role": "Sales Director",
              "prospect_role": "Head of Engineering",
              "is_current": false
            }
          },
          "is_target_company": true
        }
      ]
    }
  ],
  "custom": {
    "your_field": "value"
  },
  "timestamp": "2025-03-15T14:30:00Z"
}

Full engagement history

Pass "full_history": true in the import request to include detailed engagement history in the webhook response:
"engagement": {
  "total_engagements": 3,
  "last_engagement_date": "2025-03-15",
  "history": [
    {
      "type": "PROSPECT_LIKED",
      "date": "2025-03-15",
      "link": "https://linkedin.com/...",
      "source": "linkedin"
    },
    {
      "type": "PROSPECT_COMMENTED",
      "date": "2025-02-10",
      "text": "Great insight!",
      "link": "https://linkedin.com/...",
      "source": "linkedin"
    }
  ]
}
Possible engagement types: PROSPECT_COMMENTED, PROSPECT_LIKED, PROSPECT_REACTED, PROSPECT_RECOMMENDED, CLIENT_COMMENTED, CLIENT_LIKED, CLIENT_RECOMMENDED.

Custom data passthrough

Any data you send in the custom field of the import request is passed through to the webhook payload unchanged. Use this to correlate webhook responses with your internal records.
// Import request
{
  "contacts": [...],
  "webhook_url": "https://your-webhook.com/endpoint",
  "custom": {
    "crm_batch_id": "batch_001",
    "triggered_by": "daily-sync"
  }
}

// Webhook response includes it unchanged
{
  "status": "completed",
  "job_id": "job_abc123",
  ...
  "custom": {
    "crm_batch_id": "batch_001",
    "triggered_by": "daily-sync"
  }
}

Error payloads

When processing fails, status is "failed" and an error object is included:
{
  "status": "failed",
  "job_id": "job_abc123",
  "batch_id": "batch_xyz789",
  "summary": {
    "total_processed": 0,
    "total_opportunities": 0,
    "processing_time_seconds": 0
  },
  "error": {
    "code": "PROCESSING_ERROR",
    "message": "Failed to process contacts",
    "details": "Additional error context"
  },
  "timestamp": "2025-03-15T14:30:00Z"
}
See the full webhook payload schema in the OpenAPI spec.