Handle Failed Enrichments
A 200 response means the API processed your request — not that it found data. Robust pipelines branch on three fields in every enrichment response: isSuccess, isRetryable, and problems.
The decision table#
isSuccess | isRetryable | Typical problems flag | What to do |
|---|---|---|---|
| true | — | — | Use the data. Store personId. |
| false | true | transientScrapingVendorFailure | Retry with backoff — same input can succeed later. |
| false | false | linkedinProfileNotFound | Don’t retry. Fix or replace the input identifier; flag the source row. |
A sensible retry policy#
- Retry only when
isRetryableistrue. - Use exponential backoff with jitter — wait longer after each attempt, with a little randomness so retries don’t align: e.g. 1m → 10m → 1h, max 3 attempts.
- After the final failure, park the row in a dead-letter queue — a holding table of failed rows you revisit periodically — not an infinite retry loop.
A non-retryable failure
{
"data": null,
"isSuccess": false,
"isRetryable": false,
"inputParameters": { "professionalSocialMediaUrl": "linkedin.com/in/this-profile-is-gone" },
"problems": { "linkedinProfileNotFound": true }
}Transport-level failures#
- 429 — honor the
X-Rate-Limit-Retry-After-Secondsheader; useX-Rate-Limit-Remainingto throttle proactively. - 5xx — retry with backoff; include the
correlationIdfrom the error envelope when reporting the issue to your AggKnowledge account team. - 400 / 402 — never retry unchanged: fix the input, or top up credits.
Tip: Most non-retryable failures are preventable: normalize identifiers and run Validate before enriching. Prevention is cheaper than triage.