Bleh this is more complex than I thought. I thought I could just use a library function to encode it but when I pass in the URL and encode it it just gives the same string back. Turns out '@' is a valid symbol for a query param and does not need to be encoded. I might have to say this the URL is valid and it's the website that is wrong.
I could do something hacky and just manually replace any @ with the encoded form though. It's not hard but I would prefer not to.