I have already explained the problem details here, so i guess this link should be enough. But unfortunately I haven’t got any explanation for this behavior but got suggested to raise my issue here.
In short. When calling locations POST endpoint with the name of an existing location that was recently created (recently = today, several hours ago) then instead of getting an error in response saying that the location with this name already exists (which you would get doing the same call on the next day), you get this very location in response like if it was successfully created.
And then you can easily start using the existing location while being sure that it’s a new one.
This is expected behavior. For a short period after a location is created, if another one is attempted to be created with the same name, it will use it as an idempotency key and return the same location. The nickname is used as a unique indicator for a location. The team is aware of this and do plan on better explaining this in the documentation, so thank you for sharing. Let me know if you have further questions or concerns about this.
ok, it’s getting more clear now. But it is still not clear why using location as an idempotency key prevents the correct response Location already exists. Just curious. Is there a way to know on your side that the location in the request payload already exists?
Theoretically that’s how idempotency works. Ie in our other endpoints, like CreatePayment, if you create a payment with “XYZ” as the idempotency key, and then call CreatePayment again with the same “XYZ” as the idempotency key, then you would get back the same response (not a new payment or an error). Idempotency helps you confirm that it succeeded, in case you are unsure (such as if the network drops and you didn’t get the response from our servers). Ie it would either tell you yes it did succeed and here’s the same response again, or it didn’t succeed and now we’re creating it for you for the first time.
But here is the case that I think shows the problem in this idea. Imagine there is a restaurant chain. And let’s say they are opening two new locations. So they want to create two Square Locations as well. And now imagine they happen to do it at the same time. And their code to call the API endpoint is pretty straightforward: it calls the CreateLocation endpoint and puts the new location’s name in the payload. Now imagine the two new locations have the same name. So for both of these new locations, the endpoint call would have the same name. And given that these two calls happen within the same day, only the first call would create a new location. The second call would just receive the existing location in response. But the responses would be just identical. So both of the new restaurants would start using the same location on Square without even knowing it.
That’s the problem.
So the way I solve it now is I retrieve all the locations first, I check if there already is a location with the name equal to the one I’m about to create and if there already is one I change the name.
This way i have to always do an extra call to retrieve existing locations. While that would be much better for me to not do it and just be sure that if there already is one i will be notified about it in response.
Maybe I’m missing something… Is there a better way to handle the described situation?
PS this situation get’s much worse if you have no idea about this tricky responses behavior and don’t have a clue you have to handle it
No, I definitely agree with you and I’ve relayed the frustration previously to the team that owns this. I believe there are plans to handle this better. Ie most other endpoints (not Locations) use an actual idempotency_key, and not a random existing parameter (such as name in this case) as the idempotency key. In those endpoints, you would obviously know if you intended on making the same request versus a new request (since idempotency keys are typically uniquely generated).
In the situation that you described, you would either need to do the ListLocations to check, or check the location_id after it was created (to see if it’s different/unique among other locations).