To add to what Ewan has said, since HTTP already has “stringly” typed parameters, so it can be impossible to parse the parameters correctly. You should aim for precision in being able to express your intent. You will already have a lot of other factors to deal with, but you don’t want to have design ambiguity as part of it.
Ewan gives the counter-example of having both siteId: 1 and siteCode: “1”. That is bad, since you will eventually run into that, and it can become more and more complex. Avoiding that will make your life easier. And even if you don’t think you will have that problem, you must have logic to determine the intent of the client, but that is backwards– the client should determine their intent and be able to express it unambiguously to you by selecting an endpoint.
A single client will almost always pick one endpoint, so removing as many edge cases from that endpoint as possible will simplify usage for your clients as well. A client would rarely want to pass a siteId and siteCode to the same endpoint.
Function overloading in normal code works because of the type encoding of parameters, when that type information does not exist, you need to have another way of expressing it.
Documenting two separate endpoints will also be easier for your users. They will usually already know what sort of data they have access to and can pass in to you. Having a clearly separated set of two endpoints with exact specifications will allow them to find the one they are looking for and use that. It will be clearly documented and straightforward to use, instead of trying to understand the type differentiation between two.