DEV Community

Rahul Sharma
Rahul Sharma

Posted on

CF7 to Notion Broke on August 11, 2026 - Here Is Exactly What Happened

On August 11, 2026, Notion started strictly enforcing the Bearer prefix in Authorization headers. CF7-to-Notion plugin integrations that were working that morning were broken by that afternoon. Forms started showing errors to visitors. The Notion database list disappeared from the plugin settings. Every API call returned:

401 unauthorized: API token is invalid
Enter fullscreen mode Exit fullscreen mode

The token was not invalid. The integration was not misconfigured. Notion simply changed how strictly it validates the Authorization header format - and the plugin was sending the token without the required Bearer prefix.

This is one of the cleanest and most thoroughly documented bugs I have seen in the WordPress support forums. The developer who filed the report identified the exact line of code, proved the cause with a command-line test, wrote a working workaround, and even flagged a PHP 9 breaking change in the same plugin. The plugin team responded within days with a patch.

The Root Cause: Missing Bearer Prefix in the Authorization Header

HTTP Bearer authentication requires this exact header format:

Authorization: Bearer secret_abc123...
Enter fullscreen mode Exit fullscreen mode

The CF7 Notion addon (version 1.6.2 and earlier) was sending:

Authorization: secret_abc123...
Enter fullscreen mode Exit fullscreen mode

The raw token, no prefix. This is the relevant line from the plugin source at includes/classes/class-api-notion.php:

'Authorization' => $this->secret_token,
Enter fullscreen mode Exit fullscreen mode

Until August 11, Notion's API accepted both formats. After that date, Notion tightened its header parsing and started rejecting the bare token with a 401. The plugin code had not changed. Notion's validation had.

The developer confirmed this with a direct command-line test:

# With correct Bearer prefix — returns 200 OK
curl -H "Authorization: Bearer secret_..." https://api.notion.com/v1/databases

# Without Bearer prefix — returns 401
curl -H "Authorization: secret_..." https://api.notion.com/v1/databases
Enter fullscreen mode Exit fullscreen mode

Same token. Same endpoint. Different header format. Different result.

If You Are on Plugin Version 1.6.2 or Earlier

Update to version 1.6.3 immediately. The plugin team released the fix on August 24, 2026. No settings changes are needed after updating. The plugin adds the Bearer prefix and also includes a guard for tokens that had the prefix manually added via the workaround filter.

If your automatic updates are delayed or you cannot update right now, apply this temporary fix using the WPCode or Code Snippets plugin:

add_filter( 'add-on-cf7-for-notion/notion-api/request-args', function( $args ) {
    if (
        ! empty( $args['headers']['Authorization'] ) &&
        0 !== stripos( $args['headers']['Authorization'], 'Bearer ' )
    ) {
        $args['headers']['Authorization'] = 'Bearer ' . $args['headers']['Authorization'];
    }
    return $args;
} );
Enter fullscreen mode Exit fullscreen mode

Add this as a PHP snippet, activate it, then go to Contact in your WordPress admin and reload the Integration tab. Your Notion databases should reappear immediately.

Once you update to 1.6.3 you can safely remove this filter - the version 1.6.3 patch handles the Bearer prefix natively.

The PHP 9 Breaking Change Also In This Plugin

The same developer identified a second bug in the same code. The get_databases() pagination function contains:

sleep( 0.25 );
Enter fullscreen mode Exit fullscreen mode

sleep() takes an integer argument. Passing 0.25 (a float) silently becomes 0 in PHP 8 - the intended quarter-second throttle never happens. On PHP 8.1+, this logs a deprecation notice:

PHP Deprecated: Implicit conversion from float 0.25 to int loses precision
Enter fullscreen mode Exit fullscreen mode

On PHP 9, this becomes a TypeError - a fatal error that will break database listing entirely. The correct call is:

usleep( 250000 ); // 250,000 microseconds = 0.25 seconds
Enter fullscreen mode Exit fullscreen mode

The plugin team included this fix in version 1.6.3 as well. If you are running PHP 8.1+ you may already see the deprecation notice in your error logs. Updating to 1.6.3 fixes it.

The Broader Lesson: External API Enforcement Changes Break Integrations Silently

This incident is a precise example of a category of failure that is extremely common but almost never anticipated: an external service changes how strictly it validates its API without breaking changes to the response format, and plugins that were previously working break overnight.

Notion did not change its API version. They did not remove an endpoint. They did not change the response format. They just started enforcing an existing requirement more strictly. The plugin's requests had always been technically malformed — they just happened to work until Notion decided to start caring.

This happens with auth headers, content-type headers, API version headers, and rate limiting. The plugin that worked for two years can fail on a Tuesday morning because the receiving service tightened validation on Monday evening.

The only way to know when this happens is to have response logging on every API call. Contact Form to API logs the response from every submission attempt. When Notion started returning 401s, you would have seen it in the log on the first failed submission rather than finding out when a client called to say their form was broken.

Connecting CF7 to Notion Directly

For a more resilient CF7 to Notion integration, you can call Notion's API directly rather than relying on a dedicated plugin.

Notion's API for creating a page (database row):

POST https://api.notion.com/v1/pages
Authorization: Bearer YOUR_NOTION_TOKEN
Content-Type: application/json
Notion-Version: 2022-06-28

{
  "parent": { "database_id": "YOUR_DATABASE_ID" },
  "properties": {
    "Name": {
      "title": [{ "text": { "content": "Jane Smith" } }]
    },
    "Email": {
      "email": "jane@example.com"
    },
    "Phone": {
      "phone_number": "1234567890"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Note that Notion requires the Notion-Version header (2022-06-28 is the current stable version). Property names in the payload must exactly match the column names in your Notion database. Property types (title, email, phone_number, rich_text, etc.) must match the column type configured in Notion.

Quick Reference

Symptom Cause Fix
401 on all Notion API calls from August 11, 2026 Plugin sending token without Bearer prefix Update to v1.6.3 or apply filter workaround
Deprecation notices for sleep(0.25) in PHP logs sleep() called with float argument Update to v1.6.3 (uses usleep(250000) instead)
Will break on PHP 9 sleep(0.25) becomes TypeError Update to v1.6.3 now
Notion databases not appearing in plugin after token entry Same 401 issue Same fix as above

Top comments (0)