DEV Community

Rahul Sharma
Rahul Sharma

Posted on

CF7 Leads Landing in Pipedrive Contacts Instead of Deals? Here's Why

CF7 Leads Landing in Pipedrive Contacts Instead of Deals? Here's Why
A developer posted this on the WordPress support forums:

"I connected Contact Form 7 to Pipedrive. Web form data is going into Pipedrive under Contacts view but I want it in the Lead view. How do I fix this?"

The plugin author's reply: "The menu says 'Create New Contact' so it adds contacts. That's what it does."

Technically correct. Not very helpful.

The real issue isn't a plugin setting it's a Pipedrive data model misunderstanding that catches almost every developer building their first CF7-to-Pipedrive integration. Contacts, Leads, and Deals are three separate objects in Pipedrive, and they live in completely different parts of the CRM. Hitting the wrong API endpoint lands your data in the wrong place.

This post explains the difference, maps each to the correct API endpoint, and shows how to send CF7 submissions directly into Deals (or Leads) instead of just Contacts.

Pipedrive's Three-Object Data Model

This is the part no integration tutorial explains upfront:

Object What it is Where it lives in Pipedrive UI API Endpoint
Person (Contact) A CRM contact record — name, email, phone People tab POST /v1/persons
Lead A lightweight pre-qualified prospect not yet a deal Leads Inbox POST /v1/leads
Deal An active sales opportunity in a pipeline stage Deals / Pipeline view POST /v1/deals

Most CF7 integration plugins including the free tier of the one in this forum thread only call POST /v1/persons. That creates a Person record (Contact view). It does not create a Lead or a Deal.

If your sales team works from the Deals pipeline or the Leads Inbox, form submissions going only to Contacts are invisible to them in their daily workflow.

What You Actually Want: Deal vs Lead

Before picking an endpoint, decide which Pipedrive object fits your workflow:

Use POST /v1/deals if:

  • You want submissions to appear in a pipeline with stages (e.g., New → Qualified → Proposal → Closed)
  • Your sales team works from the Kanban or list pipeline view
  • You need to assign pipeline stage, owner, and expected close date

Use POST /v1/leads if:

  • You want a lightweight inbox for unqualified enquiries before they become deals
  • You don't need pipeline stage assignment yet
  • You want to triage first, convert to Deal later

Both require a Person to be created first you link the Deal or Lead to the Person via person_id.

The Correct API Sequence

Step 1 - Create a Person (always first)

POST https://api.pipedrive.com/v1/persons
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "name": "Jane Smith",
  "email": [{ "value": "jane@example.com", "primary": true }],
  "phone": [{ "value": "+11234567890", "primary": true }]
}
Enter fullscreen mode Exit fullscreen mode

Response gives you a person_id use it in the next call.

Step 2a - Create a Deal (pipeline view)

POST https://api.pipedrive.com/v1/deals
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "title": "Website Enquiry - Jane Smith",
  "person_id": 123,
  "pipeline_id": 1,
  "stage_id": 1,
  "status": "open"
}
Enter fullscreen mode Exit fullscreen mode

Step 2b - Create a Lead (leads inbox)

POST https://api.pipedrive.com/v1/leads
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "title": "Website Enquiry - Jane Smith",
  "person_id": 123
}
Enter fullscreen mode Exit fullscreen mode

The Lead endpoint is simpler - no pipeline or stage needed. It lands in the Leads Inbox for your team to triage.

Full CF7 Implementation (Deals Flow)

add_action('wpcf7_before_send_mail', 'cf7_to_pipedrive_deal');

function cf7_to_pipedrive_deal($contact_form) {
    if ((int) $contact_form->id() !== YOUR_FORM_ID) return;

    $submission = WPCF7_Submission::get_instance();
    if (!$submission) return;

    $data     = $submission->get_posted_data();
    $token    = defined('PIPEDRIVE_API_TOKEN') ? PIPEDRIVE_API_TOKEN : '';
    $base     = 'https://api.pipedrive.com/v1';
    $headers  = [
        'Authorization' => 'Bearer ' . $token,
        'Content-Type'  => 'application/json',
    ];

    // 1. Create Person
    $person_res = wp_remote_post("$base/persons", [
        'headers' => $headers,
        'body'    => wp_json_encode([
            'name'  => sanitize_text_field($data['your-name'] ?? ''),
            'email' => [['value' => sanitize_email($data['your-email'] ?? ''), 'primary' => true]],
            'phone' => [['value' => sanitize_text_field($data['your-phone'] ?? ''), 'primary' => true]],
        ]),
        'timeout' => 15,
    ]);

    $person = json_decode(wp_remote_retrieve_body($person_res), true);
    $person_id = $person['data']['id'] ?? null;
    if (!$person_id) return;

    // 2. Create Deal linked to Person
    wp_remote_post("$base/deals", [
        'headers' => $headers,
        'body'    => wp_json_encode([
            'title'       => 'Enquiry - ' . sanitize_text_field($data['your-name'] ?? ''),
            'person_id'   => $person_id,
            'pipeline_id' => 1,  // get your IDs from GET /v1/pipelines
            'stage_id'    => 1,  // get your IDs from GET /v1/stages
            'status'      => 'open',
        ]),
        'timeout' => 15,
    ]);
}
Enter fullscreen mode Exit fullscreen mode

To use the Leads Inbox instead, replace the second wp_remote_post call:

// 2. Create Lead linked to Person (lands in Leads Inbox)
wp_remote_post("$base/leads", [
    'headers' => $headers,
    'body'    => wp_json_encode([
        'title'     => 'Enquiry - ' . sanitize_text_field($data['your-name'] ?? ''),
        'person_id' => $person_id,
    ]),
    'timeout' => 15,
]);
Enter fullscreen mode Exit fullscreen mode

No-Code Option: Contact Form to API Plugin

If you'd rather configure this from a UI than deploy PHP, Contact Form to API lets you point directly at any Pipedrive endpoint — /persons, /deals, or /leads — set the Authorization header, and map CF7 fields to JSON keys. No code, no deployment, token updates happen in the dashboard.

Quick Lookup: Get Your Pipeline and Stage IDs

You need integer IDs for pipeline_id and stage_id. Grab them with a quick GET:

# Get pipeline IDs
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.pipedrive.com/v1/pipelines"

# Get stage IDs for pipeline 1
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.pipedrive.com/v1/stages?pipeline_id=1"
Enter fullscreen mode Exit fullscreen mode

The id field in each response object is what you pass into your Deal payload.

--

Top comments (0)