As a general rule, 500 errors should be retried. There is a rule of thumb for most error codes:
- 2xx = Everything that can be done has been done.
- 4xx = You (the caller) did something wrong or asked for something nonsensical.
- 5xx = We (the server) did something wrong.
4xx errors generally boil down to a request that is inherently bad and cannot be handled. 5xx errors are used to indicate that the server encountered a private issue, and there is no indication that your request is provably invalid.
That doesn't mean your request must have been valid. For example, let's say you send a request to fetch an item but you use an ID that doesn't exist. A server that handles the request well will give you a 404 response (or a 204. I've heard arguments either way and I think the distinction is contextual). However, if the server has a bug which leads to a null reference exception, you're likely to get a 500 response.
As the caller, when you get a 500 response, you don't know what went wrong. All you know is that the server did not actively tell you that your request is nonsensical. Which means that you cannot assume that there's no point in trying to make the same request again.
For example, maybe you received the 500 because the server database was offline. If you wait a bit and try again, it may succeed now that the database is online.
But when you receive a 4xx error, the server has actively stated that your request is unresolvable and there's no point in retrying.
This is a bit of an overgeneralization, fringe exceptions exist. For example, status 429 (too many requests) means that you (the caller) have exceeded your allotted amount of calls, but it's likely that your same request will be processed correctly if you wait until you've been allotted more requests (e.g. if you hit the daily maximum, it will work again tomorrow).
However, sul4bh is correct that this can be contextual, and that some applications may not want you to send the same request multiple times.
For example, consider a banking transaction. You send the request, and get a 500. But in reality, the server did actually process your request, but it encountered a trivial bug in the formatting of the response message.
Send your request again may be harmful, as you'll end up making several banking transactions.
However, I don't think that this is up to you (the caller) to decide when you are allowed to fire the same request and when you are not. It's the server's responsibility to clearly communicate the true state of things to the caller, and in the above scenario, it failed to do so. You can't be held responsible for being given bad information and responding correctly to the information given.
If I make a payment via online banking, and I get a 500 when I submit the transaction, I'm going to try it again. It's the most sensical response to a 500 error. To that effect, my bank actually has implemented a check. If it notices that you are making a second transfer in quick succession for the same amount and/or to the same account, it will tell you that it did in fact register the first transaction.
So this is very dependent on the server. They are expected to clearly communicate to you, and when you assume clear communication, a 500 means you should retry at a later time because the cause of the issue was serverside, not in your request.
If the server cannot clearly communicate, or the context of the application requires the caller to err on the side of never taking the same action twice, then the server's administrators need to clearly communicate that to their API's consumers, and should make reasonable efforts towards preventing erroneously taking the same action twice.