vlayervlayer docs
Conventions and errors

Data lookup errors

Error codes returned when a post or profile cannot be read, and which ones are safe to retry.

Data lookups can fail because the post or profile is not readable. They return the standard error envelope; branch on error, never on message.

{
  "error": "POST_AGE_RESTRICTED",
  "message": "This post is age-restricted, so it cannot be scraped. Ask the creator to repost without an age restriction."
}
errorHTTPRetry?Meaning
POST_AGE_RESTRICTED422NoThe post is age-gated and could not be read. Most age-gated posts are still read and succeed; for one that is not, only its author can fix this by reposting without the restriction
POST_NOT_ACCESSIBLE422NoThe post is private or otherwise not public
POST_NOT_FOUND404NoThe post no longer exists at that URL
PROFILE_UNAVAILABLE404NoThe profile does not exist or was deactivated
PROFILE_RESTRICTED403NoThe profile exists, but the platform withholds it from public lookups
SCRAPING_RATE_LIMITED429YesWait for the Retry-After header, then retry
SCRAPING_UNAVAILABLE503LaterReading the platform is temporarily unavailable
SCRAPING_ERROR502YesThe read failed for an unclassified reason

403, 404 and 422 are permanent for that post or profile. Retrying them will not change the result. 429, 502, and 503 are transient.

In a batch, a failed URL carries the same code in error.code, and a URL the batch did not finish within 100 seconds carries BATCH_TIMEOUT; send it again in a new batch.

Routes that return these codes

On the engagement verification routes:

Liker fetching reports failures on the run's status and errorMessage instead; see Instagram likers.

Handling pattern

const params = new URLSearchParams({ url: postUrl });
const res = await fetch(`${API_BASE_URL}/v1/stats?${params}`, {
  headers: { Authorization: `Bearer ${API_TOKEN}` },
});

if (res.ok) return await res.json();

const { error } = await res.json();
switch (error) {
  case "RATE_LIMITED":
  case "SCRAPING_RATE_LIMITED":
    return retryAfter(Number(res.headers.get("Retry-After") ?? 60));
  case "SCRAPING_UNAVAILABLE":
  case "SCRAPING_ERROR":
    return retryWithBackoff();
  default:
    // POST_*, PROFILE_* and VALIDATION_ERROR: permanent
    return markPostUnreadable(error);
}

Last updated on