title: HTTP status code handling in GraphQL APIs
body: <p>A lot of resources say, that GraphQL should always respond with a 200 status code, even when an error occurred:</p>
  
  <ul>
  <li><a href="https://www.graph.cool/docs/faq/api-eep0ugh1wa/#how-does-error-handling-work-with-graphcool" rel="noreferrer">https://www.graph.cool/docs/faq/api-eep0ugh1wa/#how-does-error-handling-work-with-graphcool</a></li>
  <li><a href="https://github.com/rmosolgo/graphql-ruby/issues/1130#issuecomment-347373937" rel="noreferrer">https://github.com/rmosolgo/graphql-ruby/issues/1130#issuecomment-347373937</a></li>
  <li><a href="https://blog.hasura.io/handling-graphql-hasura-errors-with-react/" rel="noreferrer">https://blog.hasura.io/handling-graphql-hasura-errors-with-react/</a></li>
  </ul>
  
  <p>Because GraphQL can return multiple responses in one response, this makes sense. When a user requests two resources in one request, and only has access to the first resource, you can send back the first resource and return a <code>forbidden</code> error for the second resource.</p>
  
  <p>However, this is just something I figured out along the way reading docs of multiple GraphQL libraries and blog posts. <strong>I didn't find anything about HTTP status codes in the offical specs, here <a href="https://spec.graphql.org/" rel="noreferrer">https://spec.graphql.org/</a> or here <a href="https://graphql.org/" rel="noreferrer">https://graphql.org/</a></strong></p>
  
  <h2>So I still have a few questions left:</h2>
  
  <ol>
  <li>Is it ok to return a HTTP 500 status code if I have an unexpected server error?</li>
  <li>Is it ok to return a HTTP 401 status code, if credentials are wrong?</li>
  <li>Should I include the <em>potential</em> HTTP status code inside the <code>errors</code> key of the GraphQL response like this</li>
  </ol>
  
  <pre><code>{
    "errors" =&gt; [{
      "message" =&gt; "Graphql::Forbidden",
      "locations" =&gt; [],
      "extensions" =&gt; {
        "error_class" =&gt; "Graphql::Forbidden", "status" =&gt; 403
      }
    }]
  }
  </code></pre>
  
  <ol start="4">
  <li>Should I match common errors like a wrong field name to the HTTP status code <code>400 Bad Request</code>?</li>
  </ol>
  
  <pre><code>{
    "errors" =&gt; [{
      "message" =&gt; "Field 'foobar' doesn't exist on type 'UserConnection'",
      "locations" =&gt; [{
        "line" =&gt; 1,
        "column" =&gt; 11
      }],
      "path" =&gt; ["query", "users", "foobar"],
      "extensions" =&gt; {
        "status" =&gt; 400, "code" =&gt; "undefinedField", "typeName" =&gt; "UserConnection", "fieldName" =&gt; "foobar"
      }
    }]
  }
  </code></pre>
  
  <p>I'd be great if you could share your experiences / resources / best practises when handling HTTP status codes in GraphQL.</p>