Skip to main content

Errors

The API uses standard HTTP status codes and returns error bodies as RFC 9457 application/problem+json.

The problem shape

{
"type": "https://papi.prospectconnect.ai/problems/validation",
"title": "Request failed schema validation",
"status": 422,
"detail": "`limit` must be between 1 and 100.",
"instance": "/v1/contacts/search",
"trace_id": "3f9a2c7e1b8d4a6f"
}
FieldMeaning
typeA URI identifying the error category. Stable — safe to branch on.
titleShort, human-readable summary of the category.
statusThe HTTP status code, repeated for convenience.
detailWhat went wrong with this specific request.
instanceThe path that produced the error.
trace_idA unique id for this request. Include it in support requests — it lets us find the exact call in our logs.

Always branch on status (or the stable type), never on the human-readable title or detail strings — those may be reworded.

Status codes

Statustype slugWhenWhat to do
400bad-requestMalformed JSON or unparseable requestFix the request body/headers.
401unauthorizedMissing, expired, or invalid tokenRe-authenticate; refresh the token.
403forbiddenToken lacks the scope or the user's role denies itDon't retry — request the scope, or the user lacks permission. See scope ∩ role.
404not-foundNo such record — or it exists but isn't visible to this user's roleVerify the id; check the user can see it.
422validationFailed schema validationRead errors[] and fix the named fields.
429rate-limitedToo many requestsBack off using the X-RateLimit-* headers. See Rate limits.
5xxserver-errorSomething failed on our sideRetry with backoff; if it persists, send us the trace_id.

Validation errors (422)

Validation failures include a errors array pinpointing each bad field — so you can surface precise messages to your users:

{
"type": "https://papi.prospectconnect.ai/problems/validation",
"title": "Request failed schema validation",
"status": 422,
"detail": "2 fields failed validation.",
"trace_id": "8c1d…",
"errors": [
{ "field": "email", "message": "must be a valid email address" },
{ "field": "limit", "message": "must be <= 100" }
]
}

The gateway validates strictly at the edge, before the request reaches any internal service. That means malformed input fails fast with a clear message instead of producing a confusing downstream error.

Handling errors well

  • Don't retry 4xx (except 429) — the request won't succeed unchanged.
  • Do retry 429 and 5xx with exponential backoff + jitter.
  • Log the trace_id on every failure; it's the fastest path to a resolution in support.
resp = requests.post(url, headers=headers, json=body, timeout=30)
if not resp.ok:
problem = resp.json()
raise RuntimeError(
f"{problem['status']} {problem['title']}: {problem.get('detail')} "
f"(trace_id={problem.get('trace_id')})"
)