The status code that gets returned should be the status code of the messenger and not the data. If you want to add a status code about the data, then please do.
If something can return null and empty and it’s valid, that is not a 404. That is a 200.
As far as a 403, the messenger is telling you that you shall not pass. There is no data. 403 is appropriate here. The return response can be anything since 403 is pretty self explanatory, but I would probably return json to be consistent. I would also use the field message. Something like the first one for this use case only.
In other cases where i do get data, I would use data, message, status (optional). But status in the json response would be status about the message.
Oh God. Those are the 2 worst ones. They are mainly used for IT tickets, not for developing software. Jira isn’t the worst, but it does lack basic features. It’s just when companies use Jira you just know you are going to have to deal with a bunch of PMs who all they care about is velocity.
There are so many other simplified alternatives these days. Basecamp is one.