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#

isSuccessisRetryableTypical problems flagWhat to do
true——Use the data. Store personId.
falsetruetransientScrapingVendorFailureRetry with backoff — same input can succeed later.
falsefalselinkedinProfileNotFoundDon’t retry. Fix or replace the input identifier; flag the source row.

A sensible retry policy#

  1. Retry only when isRetryable is true.
  2. 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.
  3. 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-Seconds header; use X-Rate-Limit-Remaining to throttle proactively.
  • 5xx — retry with backoff; include the correlationId from 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.