A few important things to ground this. First, the legacy endpoints are very forgiving in terms of HTTP response, but very strict about payload shape. If even one layer is off, HubSpot will still create the object shell with no properties populated. In 2025, this happens most often when the payload is missing the properties wrapper or when property names don’t match the internal names exactly. For example, firstname and name are valid, but First Name or companyName are silently ignored (https://developers.hubspot.com/docs/api-reference/crm-contacts-v3/guide )
Second, the ChatGPT “HubSpot connector” doesn’t validate your JSON the way Postman or curl does. If ChatGPT sends an empty object, a null value, or a string where HubSpot expects a key/value map, HubSpot happily creates a blank record. That’s why stripping it down to “just a name” still results in empties. The API call is firing, but the body is effectively unusable. This is especially common when schemas are set to read/write but the action still outputs an empty properties object at runtime.
What usually helps is testing the exact same request outside ChatGPT first. Use Postman or curl to create a contact with one property only, confirm it works, then copy that exact JSON structure back into your GPT action. Also make sure you’re not sending empty strings, HubSpot treats "" differently than not sending the property at all (https://developers.hubspot.com/docs/api-reference/crm-companies-v3/guide )
One quick check: when you inspect the execution logs, do you actually see a populated properties object being sent, or just the object type and auth? That detail usually reveals the root cause very fast.
