A common situation when designing an API is that you are told by business guys they need a set of fields for an entity. For example, product parameters can include these attributes:
"productParameters": { "weight": { value: 3, "unit": "kg" }, "colour": "black", "size": "XL", "batteriesIncluded": false }
But at the same time they tell you there can be other attributes coming in the future and what is worse, some of the parameters may stop being used (maybe in some use cases, whatever...).
My tech instinct usually leads me to try to avoid breaking API changes and suggest a generic structure that is some variant of "a list of key-value pairs" so that any such changes can fit into the schema:
"productParameters": [ { "key": "weight", "value": "3 kg" }, { "key": "colour", "value": "black" }, { "key": "size", "value": "XL" }, { "key": "batteriesIncluded", "value": "false" } ]
Note that this usually also means you use some "common denominator" type for the values, typically a string.
You could say you are being honest with your API consumers because you tell them the truth that they should expect any attribute to be present in such an object.
But there is a difference between "it can be anything anytime" and "it is this now, but we don't know what it will be in the future". You are just transferring the burden of the lack of information from your business people to the consumers of your API.
The consumers may need to write a more complex code than necessary to parse this "generic" structure and even map values for hardcoded keys they are interested in into some other structures.
So when the time comes to add or remove some of the fields/attributes/keys, formally it won't be a breaking change, however the logic dealing with your API's key-values, buried in your clients' code will actually be broken.
Especially if the API is consumed within a company, by being explicit about the current structure defined by the business, you are being more honest with your consumers instead of faking genericity.
When the structure changes and you need to make a breaking change, it will help the business people understand the cost of delaying such decisions. It will also help "fail-fast" and identify inconsistencies at the explicit API level instead of unexpected bugs suddenly starting to occur due to some hidden code not handling your "generic" structure properly.
I know these are difficult decisions... Feel free to tell me your view in a comment.