This is a variation on semantic versioning (which you should also read):
- Establish a version number for the API, with separate major and minor numbers. Include this explicitly in the JSON file and (if possible) in the protocol handshake. Start at version 1.0 (major.minor).
- When you make a backwards compatible API change, increment the minor number.
- When you make a backwards incompatible API change, increment the major number and reset the minor number to 0.
- When establishing a connection, if the major numbers don't match, fail the handshake or fall back to an older version of the code, if available.
- Don't make backwards-incompatible changes lightly (or at all).
I don't know the details of your API, but here are some examples of backwards compatible changes:
- Introducing a new message type.*
- Adding an optional field to an existing message, with the default behavior (when the field is not provided) identical to the previous behavior.
- Weakening a precondition.
- Strengthening a postcondition.
- Marking a message type as deprecated, without removing or altering it.
Here are some examples of incompatible changes:
- Removing a message type.
- Removing a field from a message type.
- Adding a mandatory field to a message type.
- Changing the behavior of a message in a way that the other side of the API could reasonably notice (e.g. introducing a caching layer is fine, returning different results is not).
- Strengthening a precondition.
- Weakening a postcondition.
Technically, you don't really need the minor number at all. You could just rely on version control to keep track of this information. But version numbers are more user friendly than commit hashes, and you might want to do feature detection with the minor number.
If you never break backwards compatibility, you don't need the major number either. But it's a good idea to have it just in case you need to make a breaking change. Such changes should be rare.
On the other hand, if your API is not published yet, and you don't have any client code which might be affected by backwards incompatibility, you can start your major number at zero instead of one, to indicate the API is provisional. Then you can just make any backwards incompatible changes you like without touching the major number, and when you're ready to "go gold," you advance to version 1.0.
* If it's possible that the message recipient is older than the sender, you have to ensure that both the sender and the recipient are capable of handling the case where the recipient does not recognize a message, or a particular field of the message. In typical server-client web APIs, this is rarely a problem, but for hardware APIs the situation may be quite different. It's possible you would have to regard this as a breaking change, which makes some of this advice considerably harder to follow.