In general, I followed the Google best practices for JSON responses to REST requests. Their structure looks like:

object {
  string code?;  // HTTP status code, added by MBARI
  string apiVersion?;
  string context?;
  string id?;
  string method?;
  object {
    string id ?
  }* params?;
  object {
    string href;  // added by MBARI
    string kind?;
    string fields?;
    string etag?;
    string id?;
    string lang?;
    string updated?; # date formatted RFC 3339
    boolean deleted?;
    integer currentItemCount?;
    integer itemsPerPage?;
    integer startIndex?;
    integer totalItems?;
    integer pageIndex?;
    integer totalPages?;
    string pageLinkTemplate /^https?:/ ?;
    object {}* next?;
    string nextLink?;
    object {}* previous?;
    string previousLink?;
    object {}* self?;
    string selfLink?;
    object {}* edit?;
    string editLink?;
    array [
      object {}*;
    ] items?;
  }* data?;
  object {
    integer code?; 
    string message?;
    array [
      object {
        integer errorCode?; // Added by MBARI
        string domain?;
        string reason?;
        string message?;
        string location?;
        string locationType?;
        string extendedHelp?;
        string sendReport?;
        string developerMessage?;  // Added by MBARI
      }*;
    ] errors?;
  }* error?;
}*;

So the responses from the API calls generally follow these guidelines:

{
  "code": XXX (HTTP STATUS CODE),
  "apiVersion":"X.X.X",
  "data": {
    "kind":"object-type",
    "fields":"field1,field2,field3",
    "items": [
        // These are the objects
    ]
  },
  "error":{
    "code": XXX (HTTP ERROR CODE),
    "message":"error message",
    "errors": [ {
        "errorCode": API_ERROR_CODE,
        "domain": "...",
        "reason": "...",
        "message": "...",
        "location": "...",
        "locationType": "...",
        "extendedHelp":"https://docs.mbari.org/api-name/errors/API_ERROR_CODE",
        "developerMessage":"..."
        },{
        ...
        }
    ]
  }
}

Note that any HTTP status information is in the headers of the response, not in the response payload (unless there is an error).