Both file extensions and query parameters are functionally very similar.
What I don’t necessarily like about query params for this, is that their usage implies filtering. It’s a cultural assumption but it’s there.
Another point: you might actually have a literal file at a similar path that you serve, typically when you cache responses (managed cache or straight from your app server). Using file extensions gives you a bit more natural affordances. It’s just overal less clunky.
http://endpoint/item?format=json or ?type=json
I never ever had a problem with that. The only reason to use a file extension would be if the request would take no query parameters.
It would never occur to me to use header information for this.