Workflow request validation fails if contact has special characters
SOLVE
I am facing a very weird and edge-case problem.
I implemented the HS request verification v3 in PHP, it is working fine until the username or any contact data (firstname, lastname, city, street, etc) contains special characters, specifically from German/Nordic/Norwegian/Danish/Finnish/Swedish languages. Examples: őűäå.
In some cases, for unknown reasons, I got a payload that contains a Unicode version of the special characters (\u00...)
When the code tries to validate the payload (and we ain't talking about how poorly designed the entire header validation)
I suspect that there is some trick or encoding/converting required for the payload to have the same as at their side when it gets hashes/signed, but I did not find any official material related to this kind of issue other than "Ask your customers not to use special characters/native characters."
Has anyone else faced this problem with the request verification?
Workflow request validation fails if contact has special characters
SOLVE
My current solution uses the raw body, but thank you for the suggestion to use `file_get_contents('php://input')`. As I investigated, one thing I saw recently: On the HS side, the first name is fine as it is rendered (Yllä), but when the HS workflow was sent to my end, it arrived as `Yll\u00e4`... and then the verification failed (the generated signature differs from the sent one). When I tried to replicate it, entering a name manually and via imports (UTF-8 character of `ö`) resulted in fine validation.
Workflow request validation fails if contact has special characters
SOLVE
Okay, today, the issue seems to have gone away. I removed the utf8_encode call as well ensured the raw body was used without anything. Now all data formats are working as intended.
Thank you for the help and for pointing out the `byte-to-byte` comparison, which solved the issue.
When signatures fail only with characters like ő or ä, it’s almost always a byte-for-byte mismatch caused by re-encoding the body or not using the exact target URL that HubSpot hashed on their side.
For v3 you need to build the string as method + full request URI + raw body + timestamp, all as the original UTF-8 bytes, then HMAC-SHA256 with your app secret and base64 the result.
Two details commonly break validation: using a parsed or re-encoded JSON instead of the raw request body, and hashing only the path instead of the full target URL including scheme, host, path, and query exactly as configured in the app. In PHP, read the body with file_get_contents('php://input') and do not json_decode before hashing.
Also pull the timestamp from X-HubSpot-Request-Timestamp and reject if it’s too old to avoid replay. HubSpot’s doc spells out the exact concatenation and headers for v3 here
Quick check on your side: are you hashing the full target URL exactly as entered in your app, and the raw php://input bytes without any JSON decoding or character normalization?
If you log the hex of the preimage bytes on both sides of your code path that handles non-ASCII names, you’ll usually see a subtle difference, like escaped sequences from a re-serialized body.
Hope this helps. When this hinges on reliable two-way sync, Stacksync handles the mapping and timing so records stay consistent without manual patches.
Did my answer help? Please mark it as a solution to help others find it too.
Ruben Burdin HubSpot Advisor Founder @ Stacksync Real-Time Data Sync between any CRM and Database
Workflow request validation fails if contact has special characters
SOLVE
My current solution uses the raw body, but thank you for the suggestion to use `file_get_contents('php://input')`. As I investigated, one thing I saw recently: On the HS side, the first name is fine as it is rendered (Yllä), but when the HS workflow was sent to my end, it arrived as `Yll\u00e4`... and then the verification failed (the generated signature differs from the sent one). When I tried to replicate it, entering a name manually and via imports (UTF-8 character of `ö`) resulted in fine validation.
Workflow request validation fails if contact has special characters
SOLVE
Hi @GBakonyi0 Thank you for reaching out to the Community! I'd like to invite some community members who are subject matter experts to join this conversation. @sylvain_tirreau@evaldas@SteveHTM - Would you be able to share any insights on this? Your expertise would be greatly appreciated. Best, Victor
Loop Marketing is a new four-stage approach that combines AI efficiency and human authenticity to drive growth. Learn More
Workflow request validation fails if contact has special characters
SOLVE
Thank you.
Some extra context: The Workflow tries to send contact data to my endpoint.
The following data is perfectly fine (csv):
First Name,Last Name,Contact owner,Contact unworked,Owner assigned date,Campaign of last booking in meetings tool,Contact priority,Likelihood to close,Currently in workflow,Number of Sales Activities,Member has accessed private content,Registered member,Country/Region Code,Create Date,Created by user ID,Email,Email Confirmed,Email Domain,Last Modified Date,Lifecycle Stage,Marketing contact status,Marketing contact status source name,Marketing contact until next update,Record source,Updated by user ID,Average Pageviews,Event Revenue,Latest Traffic Source,Latest Traffic Source Date,Latest Traffic Source Drill-Down 1,Latest Traffic Source Drill-Down 2,Number of event completions,Number of Pageviews,Number of Sessions,Original Traffic Source,Original Traffic Source Drill-Down 1,Original Traffic Source Drill-Down 2,Time First Seen,IP Country,Number of Form Submissions,Number of Unique Forms Submitted,"Date entered ""Lead (Lifecycle Stage Pipeline)""",Added To List On
g_test_2025-09-04_4_3,lastName_test2025-09-04_4_3,GB,TRUE,09-04-2025 16:26,,Low,1.32,FALSE,0,0,0,Sweden,09-04-2025 16:26,Björn Test,g.test+hs-wf-test_2025-09-04_4_3@test.io,,test.io,09-04-2025 16:26,Lead,Non-marketing contact,, --,CRM UI,GB,0,0,Offline Sources,09-04-2025 16:26,CRM_UI,userId:78453109,0,0,0,Offline Sources,CRM_UI,userId:78453109,09-04-2025 16:26,Sweden,0,0,09-04-2025 16:26,09-04-2025 16:26
But the following one is failing (csv):
First Name,Last Name,Contact owner,Contact unworked,Owner assigned date,Campaign of last booking in meetings tool,Contact priority,Likelihood to close,Currently in workflow,Number of Sales Activities,Member has accessed private content,Registered member,Country/Region Code,Create Date,Created by user ID,Email,Email Confirmed,Email Domain,Last Modified Date,Lifecycle Stage,Marketing contact status,Marketing contact status source name,Marketing contact until next update,Record source,Updated by user ID,Average Pageviews,Event Revenue,Latest Traffic Source,Latest Traffic Source Date,Latest Traffic Source Drill-Down 1,Latest Traffic Source Drill-Down 2,Number of event completions,Number of Pageviews,Number of Sessions,Original Traffic Source,Original Traffic Source Drill-Down 1,Original Traffic Source Drill-Down 2,Time First Seen,IP Country,Number of Form Submissions,Number of Unique Forms Submitted,"Date entered ""Lead (Lifecycle Stage Pipeline)""",Added To List On
g_test__Heikkilä__2025-09-04_4_1,lastName_test2025-09-04_4_1,GB,TRUE,09-04-2025 16:26,,Low,1.32,FALSE,0,0,0,Sweden,09-04-2025 16:26,Björn Test,g.test+hs-wf-test_2025-09-04_4_1@test.io,,test.io,09-04-2025 16:26,Lead,Non-marketing contact,, --,CRM UI,GB,0,0,Offline Sources,09-04-2025 16:26,CRM_UI,userId:78453109,0,0,0,Offline Sources,CRM_UI,userId:78453109,09-04-2025 16:26,Sweden,0,0,09-04-2025 16:26,09-04-2025 16:26
g_test__Göteborg__2025-09-04_4_2,lastName_test2025-09-04_4_2,GB,TRUE,09-04-2025 16:26,,Low,1.32,FALSE,0,0,0,Sweden,09-04-2025 16:26,Björn Test,g.test+hs-wf-test_2025-09-04_4_2@test.io,,test.io,09-04-2025 16:26,Lead,Non-marketing contact,, --,CRM UI,GB,0,0,Offline Sources,09-04-2025 16:26,CRM_UI,userId:78453109,0,0,0,Offline Sources,CRM_UI,userId:78453109,09-04-2025 16:26,Sweden,0,0,09-04-2025 16:26,09-04-2025 16:26
Importing them into the HS system is working fine. Setting up the workflow is also fine. Everything seems perfect. Just the header validation is failing for the second sample.
Workflow request validation fails if contact has special characters
SOLVE
Okay, today, the issue seems to have gone away. I removed the utf8_encode call as well ensured the raw body was used without anything. Now all data formats are working as intended.
Thank you for the help and for pointing out the `byte-to-byte` comparison, which solved the issue.