Skip to Content
🚀 Discko v2.0 is now available!

Webhook

Receive automatic notifications when events occur in your Discko organization.

Getting Started

Step 1: Create your endpoint

Create an HTTP endpoint that will receive POST requests from Discko:

// Example with Express.js app.post('/webhook/discko', (req, res) => { const { date, event, data } = req.body; console.log('Event received:', event); console.log('Date:', date); console.log('Data:', data); // Process your data here // Send an email, save to database, etc. res.status(200).send('OK'); });

Step 2: Configure in Discko

  1. Log in to your Discko dashboard
  2. Go to Mise en place > CRM
  3. Expand “Webhook”
  4. Enter your endpoint URL
  5. Test the connection

Step 3: Handle events

Process different event types in your endpoint:

app.post('/webhook/discko', (req, res) => { const { date, event, data } = req.body; switch (event) { case 'test': console.log('Test webhook received'); break; case 'lead.unlocked': console.log('Lead unlocked:', data.id); // Process lead (locked or unlocked) handleLeadUnlocked(data); break; default: console.log('Unknown event:', event); } res.status(200).send('OK'); });

How it works

  • Method: POST to your configured URL
  • Payload: JSON with { date, event, data } structure
  • Retry: Automatic retry with exponential backoff
  • Authentication: No signature verification (yet)

Expected Response Codes

  • 200-299: Success (no retry)
  • 300-399: Redirect (followed automatically)

Retry Policy

If your endpoint responds with an error, Discko will automatically retry delivery:

  • Retry attempts: 8 retries (9 total attempts including the initial request)
  • Retry delay: Exponential backoff using formula 2^(attempt-1) * 1000ms
    • 1st retry: 1 second
    • 2nd retry: 2 seconds
    • 3rd retry: 4 seconds
    • 4th retry: 8 seconds
    • 5th retry: 16 seconds
    • 6th retry: 32 seconds
    • 7th retry: 64 seconds
    • 8th retry: 128 seconds
  • Retryable status codes:
    • 408 Request Timeout
    • 413 Payload Too Large
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

Events

All webhooks follow this structure:

{ "date": "2024-01-15T10:30:00Z", "event": "event_name", "data": { /* event-specific data */ } }

test

Test event with empty data

Schema

The test event is an empty object.

Example

{ "date": "2024-01-15T10:30:00Z", "event": "test", "data": {} }

lead.unlocked

Lead event fired when a lead is processed (locked or unlocked)

Schema

FieldTypeDescription
idStringUnique lead ID
lockedBooleanWhether the lead is locked
urlString?Lead URL
unlockSourceString?Reason if locked: "insufficient_balance" or "out_of_free_credits"
dateDateWhen the lead was completed
statusStringStatus of the lead: "NEW", "IN_PROGRESS", "WON", or "LOST"
completionNumberCompletion percentage (0-100)
categoryString?Category of the lead
contactObjectContact information (person or company)
contact.typeStringContact type: "PERSON" or "COMPANY"
contact.firstNameString?First name
contact.lastNameString?Last name
contact.emailString?Email address
contact.phoneString?Phone number
contact.discProfileString?DISC profile type
contact.discProfileExplanationString?DISC profile explanation
contact.addressString?Address (person only)
contact.linkedinString?LinkedIn profile (company only)
contact.jobTitleString?Job title (company only)
companyObject?Company information (can be null)
company.nameString?Company name
company.addressString?Company address
company.websiteString?Company website
analysisObjectLead scoring and analysis
analysis.fitScoreNumber?Fit score (0-2)
analysis.fitScoreExplanationString?Explanation of fit score
analysis.intentScoreNumber?Intent score (0-2)
analysis.intentScoreExplanationString?Explanation of intent score
analysis.budgetString?Budget information
analysis.budgetExplanationString?Budget explanation
analysis.deadlineDate?Project deadline
analysis.deadlineExplanationString?Deadline explanation
analysis.scoreNumber?Overall lead score (0-8). Can be null when locked
summaryObjectLead summary
summary.abstractString?Brief abstract of the lead needs
summary.needsString?Raw needs expressed by the lead
summary.commentString?Additional comments
summary.categoriesArrayArray of summary categories
summary.categories[].nameStringName of the category
summary.categories[].descriptionStringDescription of the category
summary.categories[].summaryArrayArray of summary points

Note: the url field is not present when the lead is locked.

Examples

Individual
{ "date": "2024-01-15T10:30:00Z", "event": "lead.unlocked", "data": { "id": "req_abc123", "locked": false, "url": "https://app.discko.io/acme/leads/req_abc123", "date": "2024-01-15T10:30:00Z", "status": "NEW", "completion": 100, "category": "Web Development", "contact": { "type": "PERSON", "firstName": "Jane", "lastName": "Doe", "email": "jane.doe@email.com", "phone": "+1234567890", "address": "123 Main St, New York, NY", "discProfile": "Dominant", "discProfileExplanation": "Results-oriented and direct communicator" }, "company": null, "analysis": { "fitScore": 2, "fitScoreExplanation": "Strong match with our ideal customer profile", "intentScore": 2, "intentScoreExplanation": "High purchase intent, ready to move forward", "budget": "10000-15000", "budgetExplanation": "Budget aligns well with project scope", "deadline": "2024-02-15T00:00:00.000Z", "deadlineExplanation": "Needs delivery before product launch", "score": 7 }, "summary": { "abstract": "High-value lead seeking e-commerce solution with urgent timeline", "needs": "Modern e-commerce website with payment integration", "comment": "Looking for a quick turnaround", "categories": [ { "name": "E-commerce Features", "description": "Required e-commerce functionality", "summary": [ "Shopping cart integration", "Payment gateway setup", "Inventory management" ] }, { "name": "Timeline", "description": "Project timeline requirements", "summary": [ "Launch before product release", "Quick turnaround needed", "Delivery by mid-February" ] } ] } } }
Company
{ "date": "2024-01-15T10:30:00Z", "event": "lead.unlocked", "data": { "id": "req_xyz789", "locked": false, "url": "https://app.discko.io/acme/leads/req_xyz789", "date": "2024-01-15T10:30:00Z", "status": "NEW", "completion": 100, "category": "Digital Marketing", "contact": { "type": "COMPANY", "firstName": "John", "lastName": "Smith", "email": "john.smith@acme.com", "phone": "+1987654321", "linkedin": "https://linkedin.com/in/johnsmith", "jobTitle": "Marketing Director", "discProfile": "Influencer", "discProfileExplanation": "Enthusiastic and people-oriented" }, "company": { "name": "ACME Corp", "address": "456 Business Ave, San Francisco, CA", "website": "https://acme.com" }, "analysis": { "fitScore": 2, "fitScoreExplanation": "Perfect match for our B2B services", "intentScore": 2, "intentScoreExplanation": "Active evaluation phase, comparing vendors", "budget": "50000+", "budgetExplanation": "Enterprise budget, multiple projects planned", "deadline": "2024-03-01T00:00:00.000Z", "deadlineExplanation": "Want to start campaign in Q1", "score": 8 }, "summary": { "abstract": "Enterprise lead with strong fit and budget, ready to switch providers", "needs": "Comprehensive digital marketing strategy and execution", "comment": "Currently working with another agency but not satisfied", "categories": [ { "name": "Marketing Strategy", "description": "Strategic marketing requirements", "summary": [ "Full digital marketing audit", "Multi-channel campaign strategy", "Performance metrics and KPIs" ] }, { "name": "Execution Needs", "description": "Implementation and execution requirements", "summary": [ "Content creation and management", "Social media management", "PPC and SEO campaigns", "Regular reporting and optimization" ] } ] } } }
Locked
{ "date": "2024-01-15T10:30:00Z", "event": "lead.unlocked", "data": { "id": "req_locked123", "locked": true, "unlockSource": "insufficient_balance", "analysis": { "score": null }, "date": "2024-01-15T10:30:00Z" } }

Integration Examples

Slack Notification

const { WebClient } = require('@slack/web-api'); const slack = new WebClient(process.env.SLACK_TOKEN); app.post('/webhook/discko', async (req, res) => { const { event, data } = req.body; if (event === 'lead.unlocked') { const contactName = `${data.contact.firstName} ${data.contact.lastName}`; const companyInfo = data.company ? ` (${data.company.name})` : ''; await slack.chat.postMessage({ channel: '#leads', text: `🎯 New lead completed by ${contactName}${companyInfo} - Score: ${data.analysis.score}/8` }); } res.status(200).send('OK'); });

CRM Integration

const mysql = require('mysql2/promise'); app.post('/webhook/discko', async (req, res) => { const { event, data } = req.body; if (event === 'lead.unlocked') { const connection = await mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'crm' }); await connection.execute( `INSERT INTO leads ( discko_id, category, email, phone, company_name, first_name, last_name, job_title, linkedin, fit_score, intent_score, lead_score, needs, budget, abstract, deadline, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ data.id, data.category, data.contact.email, data.contact.phone, data.company?.name, data.contact.firstName, data.contact.lastName, data.contact.jobTitle, data.contact.linkedin, data.analysis.fitScore, data.analysis.intentScore, data.analysis.score, data.summary.needs, data.analysis.budget, data.summary.abstract, data.analysis.deadline, data.date ] ); await connection.end(); } res.status(200).send('OK'); });

Email Notification

const nodemailer = require('nodemailer'); const transporter = nodemailer.createTransporter({ service: 'gmail', auth: { user: process.env.EMAIL_USER, pass: process.env.EMAIL_PASS } }); app.post('/webhook/discko', async (req, res) => { const { event, data } = req.body; if (event === 'lead.unlocked') { const name = `${data.contact.firstName} ${data.contact.lastName}`; const companyInfo = data.company ? `<p><strong>Company:</strong> ${data.company.name}</p>` : ''; await transporter.sendMail({ from: 'noreply@yourcompany.com', to: 'sales@yourcompany.com', subject: `Lead unlocked: ${data.category} (Score: ${data.analysis.score}/8)`, html: ` <h2>Lead Unlocked</h2> <p><strong>Contact:</strong> ${name}</p> <p><strong>Email:</strong> ${data.contact.email}</p> <p><strong>Phone:</strong> ${data.contact.phone}</p> ${companyInfo} <p><strong>Category:</strong> ${data.category}</p> <p><strong>Lead Score:</strong> ${data.analysis.score}/8</p> <p><strong>Fit Score:</strong> ${data.analysis.fitScore}/2 - ${data.analysis.fitScoreExplanation}</p> <p><strong>Intent Score:</strong> ${data.analysis.intentScore}/2 - ${data.analysis.intentScoreExplanation}</p> <p><strong>Budget:</strong> ${data.analysis.budget}</p> <p><strong>Deadline:</strong> ${data.analysis.deadline}</p> <p><strong>Needs:</strong> ${data.summary.needs}</p> <p><strong>Abstract:</strong> ${data.summary.abstract}</p> <p><strong>Completed:</strong> ${data.date}</p> ` }); } res.status(200).send('OK'); });
Last updated on