Skip to main content

Error Formats

LLMLayer returns errors in two shapes, depending on where the request fails.

1. Structured Errors (most endpoint errors)

Endpoint-level failures return a structured envelope inside FastAPI’s detail field:
{
  "detail": {
    "error_type": "validation_error",
    "error_code": "missing_json_schema",
    "message": "json_schema is required when 'json' is in modes. ...",
    "details": { "url": "https://www.ycombinator.com" }
  }
}
FieldDescription
error_typeError category — see the table below
error_codeMachine-readable code, stable per failure case
messageHuman-readable explanation
detailsOptional context (URL, provider, status code, …)

2. Plain-String Errors (account-level guards)

Account-level checks (API key, balance, rate limit) return a plain string in detail:
{ "detail": "insufficient funds on LLMLAYER, please top up your account" }
These occur before your request is processed, so they never incur any charge.

HTTP Status Codes

StatusMeaningCharged?Retry?
400Invalid request — missing or malformed parameterNoAfter fixing the request
401Missing or invalid API keyNoAfter fixing the key
402Insufficient creditsNoAfter topping up
403Blocked target (private IP, blocked domain or port)NoNo — target not allowed
422Unprocessable — e.g. empty page content (refunded) or extraction output truncatedDepends — see RefundsAfter adjusting the request
423Billing reconciliation in progress for this keyNoYes, after a short wait
429Rate limit exceeded for your tierNoYes, with backoff
500Internal error or upstream fetch failureDepends — see RefundsYes
502Upstream service failure (e.g. brand profile, model output invalid)Depends — see RefundsYes
504Operation timeout (e.g. PDF scrape, DNS resolution)Yes

Error Types

The error_type field groups errors into categories:
error_typeUsed forTypical statuses
validation_errorBad or missing request parameters400
authentication_errorMissing API key header401
provider_errorAn upstream AI provider failed (rate limit, outage, auth)401, 429, 500
scraping_errorScrape/PDF/URL-validation failures (Scraper, PDF, URL checks)400, 403, 500, 504
search_errorWeb search failures (Answer API)500
extraction_errorExtract API failures (fetch, empty content, truncation, brand)422, 500, 502
map_errorMap endpoint failures4xx/5xx (passes upstream status)
internal_errorUnexpected server errors500
Streaming endpoints (/answer_stream, /crawl_stream) deliver mid-stream failures as SSE frames of the form {"type": "error", "error": "..."} instead of HTTP error responses, because the HTTP status is already committed once streaming starts.

Automatic Refunds

You only pay when the work happens

The Extract API debits your selected modes up front, then automatically refunds the full amount if the request fails before any AI cost is incurred:
FailureError codeStatusRefunded
Target page could not be fetchedpage_fetch_failed500 (or the target’s status)✅ Full refund
Page returned no extractable contentempty_page_content422✅ Full refund
Brand profile could not be builtbrand_fetch_failed502✅ Full refund
Refunded errors say so explicitly: “You have not been charged for this request.”
Failures that happen after AI processing has started (e.g. an upstream model outage, or output_truncated when extracted JSON exceeds the size limit) are not refunded, because the model cost was already incurred.
Account-level rejections (401, 402, 423, 429) always happen before any charge.

SDK Exception Mapping

Both official SDKs raise typed exceptions so you can branch cleanly:
ConditionPython (llmlayer.exceptions)TypeScript (llmlayer)
validation_error, or status 400 / 422InvalidRequestInvalidRequest
authentication_error, or status 401 / 403AuthenticationErrorAuthenticationError
provider_errorProviderErrorProviderError
Status 429RateLimitErrorRateLimitError
internal_error, scraping_error, search_error, map_error, or status ≥ 500InternalServerErrorInternalServerError
Anything else (e.g. 402 insufficient credits, 423)LLMLayerError (base class)LLMLayerError (base class)
All exceptions inherit from LLMLayerError, so except LLMLayerError / catch on the base class catches everything.
import {
  LLMLayerClient,
  InvalidRequest,
  AuthenticationError,
  RateLimitError,
  InternalServerError,
} from 'llmlayer';

async function withRetries<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; ; attempt++) {
    try {
      return await fn();
    } catch (error) {
      // Never retry: fix the request or the key instead
      if (error instanceof InvalidRequest) throw error;
      if (error instanceof AuthenticationError) throw error;

      // Retry with backoff: rate limits and server-side failures
      const retryable = error instanceof RateLimitError || error instanceof InternalServerError;
      if (!retryable || attempt >= maxRetries - 1) throw error;
      await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
    }
  }
}

Common Error Codes by Endpoint

CodeStatusMeaning
missing_llmlayer_api_key401No Authorization: Bearer <key> header
(plain string) LLMLAYER API KEY NOT VALID401Key is malformed, revoked, or unknown
(plain string) insufficient funds on LLMLAYER...402Credit balance too low — top up
(plain string) rate N/min exceeded on LLMLAYER429Over your tier’s requests-per-minute
CodeStatusRefunded
missing_modes / missing_json_schema / missing_query / pdf_not_supported400Nothing charged
page_fetch_failed500 / target status✅ Yes
empty_page_content422✅ Yes
brand_fetch_failed502✅ Yes
output_truncated422No (AI ran) — reduce schema fields or page size
model_json_invalid502No (AI ran) — safe to retry
CodeStatusMeaning
invalid_url / unsupported_scheme / credentials_in_url400URL malformed or not http(s)
blocked_domain / blocked_ip / blocked_port403Target not allowed (security policy)
dns_resolution_failed400Host did not resolve
url_scrape_failed / pdf_scrape_failed500Upstream fetch failed — retry or use advanced_proxy
pdf_scrape_timeout504PDF took too long
pdf_not_supported400PDF URL sent to a non-PDF endpoint — use /get_pdf_content
CodeStatusMeaning
missing_query / missing_model / missing_json_schema400Required parameter absent
invalid_search_parameters400Bad search_type/date_filter combination
query_generation_error / search_context_error500Search pipeline failure — retry
<provider>_rate_limit / <provider>_auth_error / <provider>_error429 / 401 / 500Upstream AI provider issue

Need Help?

Discord Community

Chat with other developers

Email Support