Problem Details, and an error format not invented here

Every API invents an error envelope and RFC 7807 is a perfectly good one that some client libraries already understand.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json

{
  "type": "https://example.com/probs/insufficient-stock",
  "title": "Insufficient stock",
  "status": 422,
  "detail": "Only 2 of SKU ABC-1 remain.",
  "instance": "/orders/8814",
  "available": 2
}

type is the field a client branches on and it is a URI rather than a code, which makes it globally unambiguous and dereferenceable to documentation. Extension members like available are explicitly permitted, which is what makes the format usable for real errors rather than only generic ones — and the content type is how a client knows to expect the shape.