DEV Community

Rahul Sharma
Rahul Sharma

Posted on

CF7 to Freshdesk Tickets Not Being Created - Four Causes and Exact Fixes

A developer documented a real CF7 to Freshdesk integration in a 2017 tutorial. The comments section became a support thread multiple people following the same code reported that "it just sends the email but no activity on Freshdesk." The author's debugging advice: use Postman to test the API directly, then print the PHP array to check the values.

That debugging advice is still the right starting point. Here are the four causes that produce the same symptom form submits, email arrives, no Freshdesk ticket.

Cause 1: Wrong Domain Format in the API URL

Freshdesk API calls require your full subdomain in the URL:

https://YOUR_SUBDOMAIN.freshdesk.com/api/v2/tickets
Enter fullscreen mode Exit fullscreen mode

Where YOUR_SUBDOMAIN is the part before .freshdesk.com in your Freshdesk URL. If your Freshdesk account is at acmehelp.freshdesk.com, the API endpoint is:

https://acmehelp.freshdesk.com/api/v2/tickets
Enter fullscreen mode Exit fullscreen mode

The most common mistake is entering just the subdomain (acmehelp) without the full domain, or using freshdesk.com without the subdomain prefix. Both produce a URL that either does not resolve or returns a generic Freshdesk error page rather than an API response.

Test your domain format:

curl -v "https://YOUR_SUBDOMAIN.freshdesk.com/api/v2/tickets" \
  -u "YOUR_API_KEY:X"
Enter fullscreen mode Exit fullscreen mode

If you see a JSON response (even a 401), the URL format is correct. If you see an HTML page or a connection error, the domain format is wrong.

Cause 2: API Key Authentication Format Is Not Standard

Freshdesk uses HTTP Basic authentication but with a non-standard format. The username is your API key and the password is literally the letter X:

Authorization: Basic base64(YOUR_API_KEY:X)
Enter fullscreen mode Exit fullscreen mode

This is different from most APIs. The API key goes in the username position. The password is always X not your actual password, not empty, literally the single character X.

Using wp_remote_post in PHP:

'headers' => [
    'Authorization' => 'Basic ' . base64_encode(FRESHDESK_API_KEY . ':X'),
    'Content-Type'  => 'application/json',
],
Enter fullscreen mode Exit fullscreen mode

If you enter your email and password in the Basic auth fields instead of API_KEY:X, authentication will fail with a 401 even if the credentials are otherwise correct.

Find your Freshdesk API key: In Freshdesk, click your profile picture at the top right, then Profile Settings. The API Key appears at the bottom right of the page.

Cause 3: Required Fields Missing from the Ticket Payload

Freshdesk requires at minimum two fields for every ticket:

  • subject — the ticket title/subject line
  • email — the requester's email address

Without both, Freshdesk returns a 422 Unprocessable Entity with a validation error. If your plugin or custom code maps only the message body or only the name, the ticket creation fails.

A minimal valid Freshdesk ticket payload:

{
  "subject": "Enquiry from Jane Smith",
  "description": "Message content here",
  "email": "jane@example.com",
  "status": 2,
  "priority": 1
}
Enter fullscreen mode Exit fullscreen mode

Freshdesk status codes:

  • 1 = Open
  • 2 = Pending
  • 3 = Resolved
  • 4 = Closed

Freshdesk priority codes:

  • 1 = Low
  • 2 = Medium
  • 3 = High
  • 4 = Urgent

For most CF7 contact form tickets, status: 2 (Pending) and priority: 1 (Low) are appropriate defaults.

Cause 4: The Hook wpcf7_mail_sent vs wpcf7_before_send_mail

The original tutorial code used wpcf7_mail_sent as the hook:

add_action('wpcf7_mail_sent', 'cf7_create_freshdesk_ticket', 0, 1);
Enter fullscreen mode Exit fullscreen mode

wpcf7_mail_sent fires only after CF7 has successfully sent its notification email. If CF7's mail sending fails for any reason — SMTP configuration issues, email blocked by spam filter, missing mail configuration — this hook never fires and no Freshdesk ticket is created.

The more reliable hook for API integrations is wpcf7_before_send_mail:

add_action('wpcf7_before_send_mail', 'cf7_create_freshdesk_ticket');
Enter fullscreen mode Exit fullscreen mode

This fires during the submission processing regardless of whether the email is sent successfully. For use cases where the Freshdesk ticket should always be created when someone submits the form, not only when the email delivery succeeds, use wpcf7_before_send_mail.

Complete CF7 to Freshdesk Implementation

add_action('wpcf7_before_send_mail', 'cf7_create_freshdesk_ticket');

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

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

    $data      = $submission->get_posted_data();
    $name      = sanitize_text_field($data['your-name']    ?? '');
    $email     = sanitize_email($data['your-email']        ?? '');
    $message   = sanitize_textarea_field($data['your-message'] ?? '');

    if (empty($email)) return;

    $api_key   = defined('FRESHDESK_API_KEY')    ? FRESHDESK_API_KEY    : '';
    $subdomain = defined('FRESHDESK_SUBDOMAIN')  ? FRESHDESK_SUBDOMAIN  : '';

    $response  = wp_remote_post(
        "https://{$subdomain}.freshdesk.com/api/v2/tickets",
        [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($api_key . ':X'),
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode([
                'subject'     => 'Enquiry from ' . $name,
                'description' => $message,
                'email'       => $email,
                'status'      => 2,
                'priority'    => 1,
            ]),
            'timeout' => 15,
        ]
    );

    if (is_wp_error($response)) {
        error_log('[CF7->Freshdesk] Error: ' . $response->get_error_message());
        return;
    }

    $status = wp_remote_retrieve_response_code($response);
    error_log('[CF7->Freshdesk] Response: ' . $status . ' — ' . wp_remote_retrieve_body($response));
}
Enter fullscreen mode Exit fullscreen mode

Store credentials in wp-config.php:

define('FRESHDESK_API_KEY',   'your-api-key-here');
define('FRESHDESK_SUBDOMAIN', 'yourcompany');
Enter fullscreen mode Exit fullscreen mode

No-Code Alternative

Contact Form to API handles the Freshdesk API call from the WordPress dashboard. Configure:

  • Endpoint: https://yoursubdomain.freshdesk.com/api/v2/tickets
  • Method: POST
  • Authorization: Basic + base64 of YOUR_API_KEY:X
  • Body: JSON with subject, email, description, status, priority

The response is logged for every submission so you see the Freshdesk ticket ID or the exact validation error if something fails.

Quick Diagnosis

Error Cause Fix
Connection error / HTML response Wrong domain format in URL Use https://SUBDOMAIN.freshdesk.com/api/v2/tickets
401 Unauthorized Wrong auth format Use API_KEY:X as Basic auth, not email:password
422 Unprocessable Entity Missing subject or email Include both required fields in payload
No ticket, no error Hook wpcf7_mail_sent not firing Switch to wpcf7_before_send_mail
Ticket created but no requester Email field not mapped Confirm email key is in the payload

Top comments (0)