Errors
One envelope, one set of types, predictable status codes.
Every non-2xx response from the Pivotal API lands in the same envelope:
type is one of seven values (table below). Branch on this in your client.code is a stable machine-readable string. Safe to use in switch/case logic.message is a sentence intended for a human — log it, surface it in admin tools, but don’t string-match against it.field is set only when the error points at a specific request property (validation, unique-violation).The set isn’t huge. These show up most:
Match on type for control flow, then on code if you need precision:
{ "message": "..." } — always wrapped in { "error": {...} }.type — 404 always pairs with not_found, 409 with conflict, etc. If you see them out of sync, that’s a bug — open a ticket.Zod validation errors carry their own code (the Zod issue code, e.g. invalid_type, too_small) and the field path. The message is taken straight from Zod — readable, but treat it as English copy, not a parseable format.
Example: posting a customer without name:
Posting a non-existent enum value to status:
If you hit a 5xx more than once on a single request, capture the response headers (especially X-Request-Id once we ship it) and send them to help@pivotal.app. Include the request body if it doesn’t contain secrets.