Errors

What the API returns when a request cannot be fulfilled.

The API uses standard HTTP status codes. Anything other than 200 means you did not get a record, and the body describes why.

Status codes

CodeMeaning
200Success.
400The request was malformed — for example a detail route with an empty identifier.
404No record matched, or the collection does not exist.
500Something broke on our end. Please open an issue.

Error body

curl -i https://hogwarts-api.com/api/characters/gandalf
{
  "statusCode": 404,
  "statusMessage": "Peeves has hidden this page. Try checking the trophy room.",
  "data": {
    "reason": "No character found for \"gandalf\"."
  }
}

The messages

CodestatusMessage
400That incantation was mispronounced. Check your wand movement and try again.
401The Fat Lady demands the password.
403Underage Wizardry detected! The Ministry of Magic has been notified.
404Peeves has hidden this page. Try checking the trophy room.
418I am currently a transfigured teapot (McGonagall's class went wrong).
429Too many owls! Our owlery is currently flooded with mail.
500A rogue Bludger has hit the server. Our house-elves are working on it.

The API is public, read-only and unthrottled, so in practice you will only ever meet 400, 404 and — if we have broken something — 500. The rest are implemented and waiting.

Except one. 418 has a home:

curl -i https://hogwarts-api.com/api/teapot
HTTP/1.1 418 I am currently a transfigured teapot (McGonagall's class went wrong).

It is the only endpoint that never succeeds.

Handling errors

Check the status before reading data — on an error response there is no data key, so destructuring it gives you undefined rather than a thrown error.

JavaScript
Python
const res = await fetch('https://hogwarts-api.com/api/characters/gandalf');

if (!res.ok) {
  const err = await res.json();
  // data.reason is the useful one; statusMessage is the flavour
  throw new Error(`${res.status}: ${err.data?.reason ?? err.statusMessage}`);
}

const { data } = await res.json();

Things that are not errors

  • A search with no matches returns 200 with "data": [] and "total_records": 0. That is a successful request that found nothing.
  • A page past the end is clamped to the last page and returns 200.
  • A page_size above 100 is clamped to 100 and returns 200.