Webhooks

A webhook is a way for one system to send real-time data to another system as soon as an event happens. Instead of constantly checking (polling) for updates, a webhook lets your application receive updates automatically.

Think of it like a notification system: when something important happens, the system calls your provided URL (usually an API endpoint) with the event data.


How to Use a Webhook

  1. Provide a URL: You give the system a public URL (your webhook endpoint) that can receive POST requests.
  2. Wait for Events: When a specific event occurs (like a person enrichment completing), the system sends a request to your URL with the relevant data.
  3. Handle the Request: Your server processes the data and responds with a 200 OK to confirm receipt.

Example Use Case

You want to be notified when a person's enrichment is completed. You provide a webhookUrl in the request. Once the enrichment is done, we send a POST request to your URL with the result data.

This approach is efficient, reduces load on your system, and gives you near-instant updates.

Supported event types

Example notification event:

    enum EventType {
        PersonEnrichmentCompleted  = "person.enrichment.completed"
        CompanyEnrichmentCompleted = "company.enrichment.completed"
    }
    export interface Event {
        eventType: EventType;
        data: any;
    }

"person.enrichment.completed"

Will be triggered when a contact within a bulk enrichment has been completed.

Source: POST /v2/people/enrich

If the notificationOptions.webhookUrl field is set, our server will send a POST request to that URL each time a person enrichment is completed.

To acknowledge successful receipt of the event, your server should respond with an HTTP 200 OK. If a different status is returned, we may retry the request depending on your configuration.

The request body sent by our server will include the details of the completed person enrichment, as shown below:

Request Body

application/jsonRequired
eventTypeRequiredstring
Value in: "person.enrichment.completed"
dataRequiredobject

Example webhook request from our server to your server

{
  "eventType": "person.enrichment.completed",
  "data": {
    "enrichmentID": "01973f39-f391-7b75-8812-7aad73f798f6",
    "person": {
      "companyDomain": "surfe.com",
      "companyName": "Surfe",
      "country": "France",
      "departments": [
        "Engineering",
        "R&D"
      ],
      "emails": [
        {
          "email": "david.chevalier@surfe.com",
          "validationStatus": "VALID"
        }
      ],
      "externalID": "external-id",
      "firstName": "David",
      "jobTitle": "Co-Founder & CEO",
      "lastName": "Chevalier",
      "linkedInUrl": "https://www.linkedin.com/in/david-maurice-chevalier",
      "location": "Paris, Île-de-France",
      "mobilePhones": [
        {
          "confidenceScore": 0.8,
          "mobilePhone": "+33 6 12 34 56 78"
        }
      ],
      "seniorities": [
        "Manager",
        "Head"
      ],
      "status": "COMPLETED"
    }
  }
}

Note that the data.person field is of type EnrichedPersonResponse, the same type used in the people field of the GET /v2/people/enrich/:id endpoint.

Example enrichment request with webhookUrl provided

 
curl -X POST "https://api.surfe.com/v2/people/enrich" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "include": {
      "email": true,
      "linkedInUrl": false,
      "mobile": false
    },
    "notificationOptions": {
      "webhookUrl": "https://webhook.site/d17b3a76-2336-4c18-8de9-7b44096f62b3"
    },
    "people": [
      {
        "companyDomain": "surfe.com",
        "companyName": "Surfe",
        "externalID": "external-id",
        "firstName": "David",
        "lastName": "Chevalier",
        "linkedinUrl": "https://www.linkedin.com/in/david-maurice-chevalier"
      }
    ]
  }'

"company.enrichment.completed"

Will be triggered when a company within a bulk enrichment has been completed.

Source: POST /v2/company/enrich

If the notificationOptions.webhookUrl field is set, our server will send a POST request to that URL each time a company enrichment is completed.

To acknowledge successful receipt of the event, your server should respond with an HTTP 200 OK. If a different status is returned, we may retry the request depending on your configuration.

The request body sent by our server will include the details of the completed person enrichment, as shown below:

Request Body

application/jsonRequired
eventTypeRequiredstring
Value in: "company.enrichment.completed"
dataRequiredobject

Example webhook request from our server to your server

{
 "eventType": "company.enrichment.completed",
 "data": {
  "enrichmentID": "01973b15-68d2-7937-b87c-78dd0069b2db",
  "company": {
   "externalID": "external-id",
   "name": "Surfe",
   "description": "Sales teams waste too much time on repetitive admin tasks. Surfe handles everything before the phone call - identifying target accounts, building lead lists, and enriching data. Our mission is to empower sales teams, automating the essential steps of the workflow while enhancing the human touch. Trusted by 3,000+ companies from local to global GTM needs like Google, Uber, AWS, Bolt, Pigment. Compatible with HubSpot, Salesforce, Pipedrive, and Copper CRM. As a GDPR-compliant and ISO27001-certified tool, Surfe helps your team operate from a gold standard of data, making sure everything is structured, categorized, updated, and protected. Surfe has been selected as Top 100 fastest-growing products on G2 and recognized as a Top 100 Rising European Startups by VivaTech in 2025.",
   "linkedInURL": "https://linkedin.com/company/surfe",
   "websites": [
    "surfe.com"
   ],
   "founded": "2020",
   "revenue": "10-50M",
   "employeeCount": 65,
   "keywords": [
    "crm updates",
    "reply rate",
    "linkedin sales",
    "linkedin messages",
    "synchronize linkedin",
    "contact data",
    "increase",
    "linkedin sources",
    "linkedin profiles",
    "email finder",
    "contact lists",
    "subscribing",
    "crm",
    "linked prospecting",
    "linkedin",
    "verified emails",
    "databases",
    "contact enrichment",
    "top-performing",
    "demo",
    "add prospects",
    "email addresses",
    "email lookup",
    "meetings",
    "professional email",
    "inmails",
    "emails",
    "top-performing sales",
    "prospecting",
    "average",
    "email",
    "real-time access",
    "enrich contacts",
    "rate",
    "marketing outbound",
    "secure crm",
    "contact",
    "highest reply",
    "contacts",
    "receive updates",
    "sales navigator",
    "france"
   ],
   "hqCountry": "FR",
   "hqAddress": "52 Rue Chaussée D'antin, Paris, 75009, FR",
   "industry": "IT Services",
   "subIndustry": "Internet Services & Infrastructure",
   "phones": [
    ""
   ],
   "digitalPresence": [
    {
     "name": "LinkedIn",
     "url": "https://www.linkedin.com/company/surfe"
    },
    {
     "name": "Twitter",
     "url": "https://twitter.com/surfehq"
    },
    {
     "name": "Facebook",
     "url": "https://www.facebook.com/surfehq"
    },
    {
     "name": "Instagram",
     "url": "https://www.instagram.com/surfehq/"
    }
   ],
   "fundingRounds": [
    {
     "name": "Seed Round - Surfe",
     "amount": 9999999999,
     "amountCurrency": "$",
     "announcedDate": "2021-01-01",
     "leadInvestors": [
      "Investor A",
      "Investor B"
     ]
    }
   ],
   "ipo": {
    "date": "2021-01-01",
    "sharePrice": 999999999,
    "sharePriceCurrency": "$"
   },
   "isPublic": false,
   "followersCountLinkedin": 8896,
   "status": "COMPLETED"
  }
 }
}

Note that the data.company field is of type EnrichedCompanyResponse, the same type used in the company field of the GET /v2/company/enrich/:id endpoint.

Example enrichment request with webhookUrl provided

 
curl -X POST "https://api.surfe.com/v2/company/enrich" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "companies": [
      {
        "domain": "surfe.com",
        "externalID": "external-id"
      }
    ],
    "notificationOptions": {
      "webhookUrl": "https://webhook.site/d17b3a76-2336-4c18-8de9-7b44096f62b3"
    },
  }'

On this page