How to select a JSONPath key with a dot
Use a quoted name selector to select the value of a JSON key that contains a dot. The expression $['shipping.city'] looks for one member named shipping.city at the root. The expression $.shipping.city takes two steps, first into shipping and then into its city member.

Follow each path through the object
Consider this JSON object. {"shipping.city":"Siem Reap","shipping":{"city":"Phnom Penh"}}. The root has two members, named shipping.city and shipping. The value of shipping is another object with its own city member.
Use $['shipping.city'] to get the string Siem Reap. Use $.shipping.city to get Phnom Penh. With bracket notation throughout, the second expression is $['shipping']['city']. Each pair of brackets selects one name from the current object, so the two bracketed expressions select different values.
Put the complete member name inside the quotes
The quotes inside the brackets delimit the key name. A dot inside that name is one of its characters. A dot in the shorthand syntax introduces another step in the path. Start at $ for the root, and add one step for each level you actually need to enter.
If a literal key occurs inside an object, reach that object first. For a payload shaped like {"order":{"shipping.city":"Siem Reap"}}, the expression is $['order']['shipping.city']. The first bracket enters order, and the second selects its single dotted member.
- Inspect the JSON and identify the object that owns the key.
- Use one quoted bracket selector for the whole dotted name.
- Run the expression in your JSONPath tool and compare its result with the value in that object.
Check the actual member in JSON Editor & Diff
JSON Editor & Diff offers a Tree view and path-based comparison results. Use the tree when a dot-separated path is ambiguous. In the example, inspect the literal shipping.city member at the top level, then expand shipping to see its separate city child.
When copying a path into a JSONPath tool, write the selector from the structure you inspected. Check the returned value as well as the label. For a comparison involving two similar fields, this makes it possible to confirm which change belongs to which member.
Trace the path again if the result is empty
Confirm the input object and the exact spelling of the key, including punctuation and case. A name selector has no match if that object lacks the exact name. For example, the literal selector has no match on an input that contains only the nested shipping object.
After confirming both paths in the sample, follow the same steps on your own input. If a later step is empty, inspect the object reached by the previous step and check whether it has the member you expected.
Questions
Can I write the nested path using only brackets?
Yes. $['shipping']['city'] takes the same two steps as $.shipping.city in this example.
What if the literal key is inside another object?
Select the containing object first, then select the dotted name as a whole. For example, $['order']['shipping.city'] takes those two steps.
Why did a query return the wrong city?
Inspect whether the expression selects the complete key in one step or enters a nested object. The two forms can both return a value when both members exist.