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"
}
| Field | Meaning |
|---|---|
type | A URI identifying the error category. Stable — safe to branch on. |
title | Short, human-readable summary of the category. |
status | The HTTP status code, repeated for convenience. |
detail | What went wrong with this specific request. |
instance | The path that produced the error. |
trace_id | A 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
| Status | type slug | When | What to do |
|---|---|---|---|
400 | bad-request | Malformed JSON or unparseable request | Fix the request body/headers. |
401 | unauthorized | Missing, expired, or invalid token | Re-authenticate; refresh the token. |
403 | forbidden | Token lacks the scope or the user's role denies it | Don't retry — request the scope, or the user lacks permission. See scope ∩ role. |
404 | not-found | No such record — or it exists but isn't visible to this user's role | Verify the id; check the user can see it. |
422 | validation | Failed schema validation | Read errors[] and fix the named fields. |
429 | rate-limited | Too many requests | Back off using the X-RateLimit-* headers. See Rate limits. |
5xx | server-error | Something failed on our side | Retry 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(except429) — the request won't succeed unchanged. - Do retry
429and5xxwith exponential backoff + jitter. - Log the
trace_idon 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')})"
)