One of the most complex challenges in API integrations is handling JSON responses containing **dynamic keys**. Dynamic keys are property keys that are not fixed names, but instead change depending on user IDs, timestamps, or product codes. In this article, we explain how to parse these unpredictable JSON payloads within the static constraints of Salesforce Apex.

The Problem with Static Class Mapping

Static deserialization methods (like JSON.deserialize()) require class variables to perfectly match the JSON keys. Consider this payload containing dynamic user IDs as keys:

{
    "users": {
        "usr_101": { "name": "Alice" },
        "usr_102": { "name": "Bob" }
    }
}

Because the keys "usr_101" and "usr_102" change dynamically, you cannot define them statically as class properties. Attempting to do so would result in compile errors or unmapped properties.

Solution 1: Map-Based Deserialization

The standard way to resolve dynamic key scenarios is to parse the payload as a generic key-value map. Instead of modeling the entire structure, map only the static portion, and cast the dynamic child nodes to a Map<String, Object>:

String payload = '{"users": {"usr_101": {"name": "Alice"}, "usr_102": {"name": "Bob"}}}';

// Parse statically to root level
Map<String, Object> root = (Map<String, Object>) JSON.deserializeUntyped(payload);
Map<String, Object> usersMap = (Map<String, Object>) root.get('users');

// Loop through dynamic keys
for (String userId : usersMap.keySet()) {
    Map<String, Object> userData = (Map<String, Object>) usersMap.get(userId);
    System.debug('User ID: ' + userId + ', Name: ' + userData.get('name'));
}

This allows your code to process any dynamic ID structure without requiring class adjustments.

Solution 2: Pre-Processing JSON via String Manipulation

If you prefer working with type-safe wrapper classes, you can pre-process the raw JSON string before deserializing it. By converting the dynamic key structure into a standard array format, you can deserialize it into list properties.

For example, you can write a utility method to replace dynamic keys with static array labels:

Original Dynamic Keys:

"users": {
    "usr_101": { "name": "Alice" }
}

Converted Array Structure:

"users": [
    { "id": "usr_101", "name": "Alice" }
]

By using standard regular expressions or string replacement to reformat the payload, you can then deserialize it directly into a standard list wrapper, preserving all the compilation checking benefits of wrapper classes.

Best Practices for Dynamic JSON in Salesforce

Conclusion

While dynamic JSON keys complicate static Apex compilation, combining untyped parsing maps with type-safe wrapper models allows you to handle any payload structure gracefully. Selecting the right balance between maps and classes keeps your Salesforce integration robust and performant.