Why do you think 403 is the wrong error code? Based on the spec it seems entirely appropriate to me:
> HTTP 403 provides a distinct error case from HTTP 401; while HTTP 401 is returned when the client has not authenticated, and implies that a successful response may be returned following valid authentication, HTTP 403 is returned when the client is not permitted access to the resource despite providing authentication such as insufficient permissions of the authenticated account.[a]
> Error 403: "The server understood the request, but is refusing to authorize it." (RFC 7231)
I thought the best response from the article was the 426 Upgrade Required. That way you can throw in an Upgrade: https field in the response. It makes it immediately clear that something weird is going on. 403s are common, my first thought would be a badly-configured API key which lacks the expected permissions.
You do not throw 403 if the client is authorized to access whatever resource it's trying to.
The 426 on the sibling comment is great, though. But if you don't find an error code for your case, you don't go and redefined a well defined one. You use 400 (or 500).
> HTTP 403 provides a distinct error case from HTTP 401; while HTTP 401 is returned when the client has not authenticated, and implies that a successful response may be returned following valid authentication, HTTP 403 is returned when the client is not permitted access to the resource despite providing authentication such as insufficient permissions of the authenticated account.[a]
> Error 403: "The server understood the request, but is refusing to authorize it." (RFC 7231)