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-...
My quesiton is whether such endpoint design is a good practice or a typical bad practice?
Same answer as others, different take:
As far as REST is concerned, these resource identifiers are all different; they identify different resources (that happen to share the same ...
Option 1. Always Option 1.
Why? Because the only way to directly upload something to S3 is via the AWS APIs and to use the AWS APIs you need an AWS key - and you should never distribute your AWS keys to your end users.
The obvious flaw is that I could have siteId: 1 and siteCode: "1", but more generally do I really want to base my routing on whether a variable parses as an int or string?
There is no reason not to have two endpoints, one for each query, which makes your API unambiguous and easier to code.
/sites/1/buildings/5 //default to ...
Instead of describing your URL scheme as:
/sites/<site id or site code>/buildings/<building id or building code>
Why not describe it as:
Some of your designations for sites and buildings being classified as ids respectively codes looks like an internal implementation-detail which nobody cares about,...
REST itself is separate from the HTTP protocol.
A Rest based response should represent the current state of the conversation, or at least the delta of change in the state. This would generally be a description of anything new, and information about things they can now do. Exactly like a web page, which describes information (the content) and has links/forms ...
There are HTTP headers for what you are looking for.
The Origin header used by browsers informs of the websites which make the request. If the authorized client foo.com embedded script is stolen, you can detect unauthorized websites and simply return a 401 (Unauthorized) flag.
The Referer header on the HTTP request does a similar job but includes ...