This page describes the data Letterdrop sends to your webhook when a lead with a competitor signal passes through a workflow, what each field means, and how to add extra fields.
How it works
- Letterdrop sends one webhook request per lead, each time a lead with a competitor signal is surfaced
- The body is a flat JSON object. There are no nested objects or arrays; lists (such as multiple competitor names) arrive as comma-separated strings.
- Every default field is always present. A field with no value arrives as an empty string (
""), notnulland not omitted.
- Flags are real JSON booleans (
true/false). Dates areYYYY-MM-DDstrings; timestamps are ISO 8601 in UTC.
- You can add your own key/value pairs on top of the default body (see Custom fields below).
Example payload
Sample values below are illustrative.
{
"webhook_type": "competitor_deal",
"name": "Jane Doe",
"linkedin_vanity_name": "jane-doe",
"linkedin_url": "https://www.linkedin.com/in/jane-doe",
"profile_picture": "https://cdn.letterdrop.co/pictures/00000000-0000-0000-0000-000000000000",
"job_title": "Head Of Revenue Strategy & Operations",
"region": "Texas",
"country": "United States",
"company_name": "Acme",
"company_website": "acme.com",
"company_size": "51-200",
"company_country": "Us",
"company_linkedin_url": "https://www.linkedin.com/company/acme",
"competitor_name": "Globex",
"latest_competitor_name": "Globex",
"all_competitor_names": "Globex",
"latest_competitor_domain": "",
"all_competitor_domains": "",
"competitor_deal_priority": "medium",
"stale": false,
"best_fit": false,
"best_fit_reasoning": "",
"role_of_contact_with_signal": "buyer",
"sales_cycle_stage": "early_stage",
"sales_cycle_stage_label": "Early Stage",
"sales_cycle_reasoning": "A Globex Account Executive is connected with Jane Doe, Acme's Head of Revenue Strategy & Operations, whose role is relevant to evaluating revenue and operations software.",
"latest_opp_stage": "",
"latest_opp_stage_label": "",
"latest_opp_start_date": "",
"latest_opp_close_date": "",
"latest_opp_account_owner_name": "",
"latest_opp_account_owner_email": "",
"latest_opp_id": "",
"all_opportunities": "No opportunities",
"recommended_action": "",
"linkedin": false,
"email": false,
"call": false,
"is_historic_signal": false,
"activity_date": "2026-08-13",
"activity_timestamp": "2026-08-13T14:04:24Z",
"collected_date": "2026-08-13",
"engaged_with_full_name": "",
"engaged_with_company_name": "Globex",
"engaged_with_job_title": "Mid Market - Account Executive",
"engaged_with_linkedin_profile": "",
"engagement_type": "connection",
"engaged_with_post_url": "",
"engaged_with_post_body": "",
"engagement_comment": "",
"engagement_date": "2026-08-13"
}Default fields
Event
Field | Type | Description | Example |
webhook_type | string | The kind of event. Always competitor_deal for competitor signals; use it to route payloads if one endpoint receives several Letterdrop webhooks. | competitor_deal |
Lead (the person who produced the signal)
Field | Type | Description | Example |
name | string | Lead's full name. | Jane Doe |
linkedin_vanity_name | string | The lead's LinkedIn profile slug. Stable identifier; good as a dedupe key. | jane-doe |
linkedin_url | string | Full LinkedIn profile URL. | https://www.linkedin.com/in/jane-doe |
profile_picture | string | URL of the lead's profile photo. | https://cdn.letterdrop.co/pictures/... |
job_title | string | Lead's current job title. | Head Of Revenue Strategy & Operations |
region | string | Lead's state or region. | Texas |
country | string | Lead's country. | United States |
Lead's company
Field | Type | Description | Example |
company_name | string | Company the lead works at. | Acme |
company_website | string | Company domain. Best key for matching to a CRM account. | acme.com |
company_size | string | Employee-count band. | 51-200 |
company_country | string | Company HQ country as a two-letter code. Casing can vary (for example Us), so normalise before comparing. | Us |
company_linkedin_url | string | The company's LinkedIn page URL. | https://www.linkedin.com/company/acme |
Competitor
Field | Type | Description | Example |
competitor_name | string | The competitor this signal is about. | Globex |
latest_competitor_name | string | The competitor from the account's most recent signal. | Globex |
all_competitor_names | string | Every competitor the account has engaged with, comma-separated. | Globex, Initech |
latest_competitor_domain | string | Domain of the latest competitor. Can be empty. | globex.com |
all_competitor_domains | string | Domains of all competitors, comma-separated. Can be empty. | globex.com, initech.com |
Deal assessment (Letterdrop's read on the account)
Field | Type | Description | Example |
competitor_deal_priority | string | How urgently to act. One of high, medium, low, nurture. | medium |
sales_cycle_stage | string | Letterdrop's estimate of where the account sits in the competitor's sales cycle, inferred from observed activity. One of aware_of_competitor, historical, prospecting, early_stage, late_stage, current_customer. | early_stage |
sales_cycle_stage_label | string | Human-readable version of the stage. | Early Stage |
sales_cycle_reasoning | string | Plain-language explanation of why the account got this stage and priority. | A Globex Account Executive is connected with... |
role_of_contact_with_signal | string | The lead's likely role in a buying decision. | buyer, gatekeeper |
best_fit | boolean | Whether the account matches your ideal customer profile. | false |
best_fit_reasoning | string | Why the account was marked best fit. Empty when best_fit is false. | The account matches the industries and company sizes seen in closed-won customers. |
stale | boolean | Whether Letterdrop considers the account's signal stale (no longer fresh enough to act on). | false |
is_historic_signal | boolean | true when the engagement happened at an unknown point in the past (for example a connection that already existed when monitoring started) rather than being newly observed. | false |
Signal (what happened)
Field | Type | Description | Example |
engagement_type | string | The kind of interaction. Possible values: connection, prospect liked competitor post, prospect commented on competitor post, prospect followed competitor, competitor commented on prospect post, competitor liked prospect post, competitor followed prospect. | connection |
engagement_date | string (date) | Date the engagement happened. | 2026-08-13 |
activity_date | string (date) | Date of the activity that triggered this webhook. | 2026-08-13 |
activity_timestamp | string (ISO 8601, UTC) | Same activity, with time. | 2026-08-13T14:04:24Z |
collected_date | string (date) | Date Letterdrop detected the signal. | 2026-08-13 |
engaged_with_company_name | string | Company of the person the lead engaged with (the competitor). | Globex |
engaged_with_job_title | string | Job title of the competitor employee involved. | Mid Market - Account Executive |
engaged_with_full_name | string | Name of the competitor employee. Can be empty. | "" |
engaged_with_linkedin_profile | string | LinkedIn URL of the competitor employee. Can be empty. | "" |
engaged_with_post_url | string | URL of the post involved. Empty for connections and follows. | https://www.linkedin.com/feed/update/urn:li:share:... |
engaged_with_post_body | string | Text of that post. Empty for connections and follows. | "" |
engagement_comment | string | The comment text, when the engagement was a comment. | Spot on! |
Your CRM (populated when a CRM is connected)
Field | Type | Description | Example |
latest_opp_stage | string | Internal stage ID of the account's most recent opportunity in your CRM. | qualifiedtobuy |
latest_opp_stage_label | string | Display name of that stage. | Discovery |
latest_opp_start_date | string (date) | Created date of the latest opportunity. | 2025-08-15 |
latest_opp_close_date | string (date) | Close date of the latest opportunity. | 2025-12-15 |
latest_opp_account_owner_name | string | Account owner's name. | Jane Smith |
latest_opp_account_owner_email | string | Account owner's email. Useful for routing alerts to the right rep. | jane@yourco.com |
latest_opp_id | string | CRM ID of the latest opportunity. | 31234567890 |
all_opportunities | string | Text summary of every opportunity on the account (name, amount, owner, pipeline, dates, stage, status). No opportunities when there are none. | No opportunities |
Recommended outreach
Field | Type | Description | Example |
recommended_action | string | Letterdrop's suggested channel mix for this lead. Empty when no outreach is recommended. | LinkedIn + Call |
linkedin | boolean | LinkedIn outreach is recommended. | false |
email | boolean | Email outreach is recommended. | false |
call | boolean | A call is recommended. | false |
Custom fields
In the Send to Webhook step you can add any number of custom fields. Each one is a key you name plus a value, and it is appended to the default body. The value can be:
- Static text, for example
source: "letterdrop"orcontact_type: "Contact with signal".
- A variable written as
{{variable_name}}, filled in per lead at send time.
- A mix of both, for example
{{lead_first_name}} at {{lead_company_name}}.
A variable with no value for a given lead is sent blank.
Variables available for custom fields
Many of these are not in the default body, so custom fields are how you get them into your system.
Lead info
Variable | What it holds |
{{lead_first_name}} | First name |
{{lead_last_name}} | Last name |
{{lead_full_name}} | Full name |
{{lead_job_title}} | Job title, e.g. VP of Marketing |
{{lead_location}} | Lead's location, e.g. New York |
{{lead_email_address}} | Email address, e.g. john@acme.com |
{{lead_phone_number}} | Phone number, e.g. +1 555 123 4567 |
{{lead_linkedin_url}} | LinkedIn profile URL |
{{lead_company_name}} | Company name |
{{lead_company_website}} | Company domain, e.g. abbott.com |
{{lead_company_linkedin_url}} | Company LinkedIn URL |
{{lead_company_location}} | Company location |
{{lead_company_size}} | Employee band, e.g. 51-200 |
{{lead_company_industry}} | Industry, e.g. Technology, Information and Internet |
{{lead_first_engaged}} | Date of the lead's first engagement |
{{lead_last_engaged}} | Date of the most recent engagement |
{{lead_last_engaged_timestamp}} | Same, as an ISO timestamp |
{{lead_activities_count}} | Number of recorded activities |
{{lead_last_activity_type}} | Type of the last activity, e.g. like |
{{lead_last_activity}} | Date of the last activity |
{{lead_last_activity_timestamp}} | Same, as an ISO timestamp |
{{lead_linkedin_activity_history}} | Recent LinkedIn posts, comments, reactions and connections |
{{wr_company_overview}} | Short overview of the lead's company: what it does, who it sells to, competitors |
Lead's LinkedIn profile
Variable | What it holds |
{{lead_linkedin_about_section}} | About section |
{{lead_linkedin_job_history}} | Job history |
{{lead_linkedin_education}} | Education |
{{lead_linkedin_licenses_and_certs}} | Licenses and certifications |
{{lead_linkedin_skills}} | Skills |
{{lead_linkedin_courses}} | Courses |
{{lead_linkedin_recent_posts}} | Posts from the last 3 months |
{{lead_linkedin_full_profile}} | The full profile as text |
Competitor deal info
Variable | What it holds |
{{latest_competitor_name}}, {{all_competitor_names}} | Latest / all competitors engaged |
{{latest_competitor_domain}}, {{all_competitor_domains}} | Latest / all competitor domains |
{{competitor_deal_priority}} | high, medium, low or nurture |
{{best_fit}}, {{best_fit_reasoning}} | ICP fit flag and the reasoning |
{{role_of_contact_with_signal}} | buyer or gatekeeper |
{{is_historic_signal}} | true / false |
{{collected_date}} | Date the signal was collected |
{{sales_cycle_stage}}, {{sales_cycle_stage_label}} | Stage ID and display label |
{{sales_cycle_reasoning}} | Why the account got its stage |
{{competitor_customer_estimated_renewal_date}} | For competitor customers, the estimated renewal date |
{{competitor_customer_optimal_outreach_date}} | For competitor customers, the suggested date to reach out ahead of renewal |
{{latest_opp_stage}}, {{latest_opp_stage_label}} | Latest CRM opportunity stage ID and label |
{{latest_opp_start_date}}, {{latest_opp_close_date}} | Latest opportunity dates |
{{latest_opp_account_owner_name}}, {{latest_opp_account_owner_email}} | Account owner |
{{latest_opp_id}} | Latest opportunity ID |
{{all_opportunities}} | Text summary of every opportunity on the account |
{{all_past_activities}} | Dated log of every competitor signal for the lead, e.g. Jul 16, 2026: Connected with Jane Smith, Senior Account Executive at Acme. |
{{recommended_action}} | Suggested channel mix, e.g. LinkedIn + Call |
{{linkedin}}, {{email}}, {{call}} | Per-channel recommendation flags |
Engaged-with info
Variable | What it holds |
{{engaged_with_company_name}} | Company of the person or post the lead engaged with |
{{engaged_with_job_title}} | That person's job title |
{{engaged_with_post_url}} | URL of the post |
{{engaged_with_post_body}} | Text of the post |
{{engagement_type}} | Type of engagement (same values as the default field) |
{{engagement_date}} | Date of the engagement |
{{engagement_comment}} | Comment text, if any |
Web research (about the lead's company)
Variable | What it holds |
{{wr_funding}} | Recent funding and financial news |
{{wr_product_launches}} | Recent product launches |
{{wr_competitive_pressure}} | Competitive moves affecting the company |
{{wr_execs_in_press}} | Executives mentioned in the press |
{{wr_regulatory}} | Regulatory news |
{{wr_hiring}} | Hiring activity |
{{wr_full_research}} | The full research output |
Your CRM
Variable | What it holds |
{{contact_crm_activity}} | The contact's recent emails, calls, meetings, notes and tasks from your connected CRM. Blank if not configured for the lead. |
Your company
Variable | What it holds |
{{your_company_name}} | Your company name |
{{your_company_description}} | Your company description |
{{your_company_website}} | Your website |
{{product_pitch}} | Your saved product pitch |
Miscellaneous
Variable | What it holds |
{{llm_question_filter_reasoning}} | Why the lead passed an AI question filter earlier in the workflow |
{{post_boolean_filter_reasoning}} | Why a post passed a post filter earlier in the workflow |
{{misc_current_date}} | Send date, YYYY-MM-DD |
{{misc_current_time}} | Send time, HH:mm |
{{workflow_name}} | Name of the workflow that sent the webhook |
{{at_mention_sender_in_slack}} | Slack @mention for the assigned sender, e.g. <@U07A1BC2D3E> |
Implementation notes
- Matching to your CRM: use
company_websitefor the account andlinkedin_url(orlinkedin_vanity_name) for the contact.
- Email and phone are not in the default body. Add
{{lead_email_address}}and{{lead_phone_number}}as custom fields if you need them.
- Default keys differ from variable names. The default body uses short keys (
name,job_title,company_name), while the variables use alead_prefix ({{lead_full_name}},{{lead_job_title}},{{lead_company_name}}). Custom fields arrive under whatever key you choose.
- Treat empty strings as "unknown". Post fields are only filled for likes and comments; CRM fields only when a matching opportunity exists.
- Expect repeat deliveries for the same person. A lead can produce several signals over time, each sending its own webhook, so upsert rather than insert.
