Skip to main content
Peel returns errors in two shapes:
  • HTTP errors come from the Peel host itself, such as a wrong API key, a bad request shape, an API not found, or an endpoint that is not ready.
  • Runtime execution errors come from a :call request where the compiled endpoint ran but failed to produce a successful result. These return the same normalized runtime envelope as successful calls. The outer HTTP status usually mirrors the envelope’s status_code, so runtime errors can be 403, 422, 429, 502, 503, 504, or another target/upstream status rather than always 200.
  • Build failures appear on GET /v1/apis/{api_id} when an API has status: "failed" and on GET /v1/apis/{api_id}/health when health returns status: "build_failed". These use failure_reason_code plus a structured failure.artifact, not the runtime response envelope.
For endpoint calls, check both layers: the HTTP status first, then status, status_code, and error_code if the response body is a runtime envelope. Host/setup errors may only include error or code; runtime errors include the normalized envelope. For failed builds, inspect failure_reason_code and failure.artifact on the API detail or failed-health response.

HTTP errors

StatusWhen it firesFix
400Request body or path did not parse, such as bad JSON, an invalid api_id, or a missing required field.Validate against the endpoint’s published schema in Inspect the contract.
401Missing or invalid X-API-Key.Set the header on every request. See Authentication.
403MCP OAuth scopes are insufficient for the tool you called.Request the correct scope: mcp:read, mcp:write, or mcp:tools.
404 on GET /v1/apis/{api_id}The api_id does not exist for this account.Confirm the ID with GET /v1/apis.
404 on :callThe endpoint_name is not published on this API. The response includes available_endpoints.Copy a name from available_endpoints or re-inspect with GET /v1/apis/{api_id}.
409 on :callThe API is not completed yet, or a previous build or revise is still running. The response includes status.Poll GET /v1/apis/{api_id} until status is completed.
409 on /respondThe API is not currently in needs_input.Re-fetch the API. Only send /respond when status is needs_input.
409 on exportsThe API exists, but Peel has not published exportable endpoints yet. The response code is API_NOT_EXPORTABLE.Inspect GET /v1/apis/{api_id} or GET /v1/apis/{api_id}/health, then wait, revise, or rebuild.
429The build queue is saturated, or a per-actor rate limit was hit. The response includes a Retry-After header.Respect Retry-After and retry. See Credits and limits.

Runtime error codes

When :call returns a runtime envelope with status: "error" or status: "timeout", the error_code field tells you what happened inside the compiled runtime. These are domain-specific errors: Peel reached the compiled endpoint execution path, but the compiled contract failed to produce data.
error_codeHTTP statusMeaningFix
endpoint_not_found404The compiled endpoint refers to a stored step that no longer resolves.Rebuild the API with POST /v1/apis/{api_id}/rebuild.
extraction_failed422The transport succeeded but the parser could not extract a result from the response.Check API health. If degraded, rebuild.
timeout504The target host took longer than the runtime budget.Retry once. If it persists, rebuild. The target may have changed behavior.
budget_exceeded402The account is out of credits for this call.Top up credits. See Credits and limits.
transport_error502The underlying HTTP request to the target failed, such as connection reset, DNS, or TLS failure.Retry once. If it persists, the site may be down or blocking the compiled transport.
upstream_errorUpstream statusA deterministic replay endpoint reached the target API, but the target returned a non-success status such as 429, 403, or 5xx.Check data.upstream_error_kind. For rate_limited, wait or configure the target API key if the endpoint supports one. For blocked, revise the API to target a public deterministic surface.
captcha_blocked403The target responded with a CAPTCHA challenge, such as Cloudflare Turnstile, hCaptcha, reCAPTCHA, DataDome, or PerimeterX.Do not retry. Peel does not solve CAPTCHAs. Revise the API to target a different surface, such as the site’s RSS or Atom feed, a public JSON endpoint, or a less-protected section.
Each runtime error also sets the outer HTTP status to the value in the table above, so you can branch on either layer.

Build failures

Errors during build are visible in GET /v1/apis/{api_id} when status is failed. The same failure object is also present in GET /v1/apis/{api_id}/health when that route returns status: "build_failed":
{
  "api": {
    "id": "4d0d8c18-3a06-4d53-9a57-2e5aa3f8c0cc",
    "status": "failed",
    "failure_reason_code": "compile_unpublishable_output",
    "failure": {
      "category": "compile_quality",
      "code": "compile_unpublishable_output",
      "message": "The compiler produced output that did not meet the publishable API quality bar.",
      "non_publishable_reason": "artifact_publishability_failed",
      "recommended_action": "revise_task",
      "retryable": false,
      "refund_reviewable": true,
      "artifact": {
        "attempted_strategies": ["custom_api_compiler"],
        "billing_disposition": "refund_review",
        "blocked_policy": null,
        "evidence_refs": ["evidence/rendered.html"],
        "failure_class": "runtime_verification_failed",
        "retryability": "not_retryable",
        "schema_version": 1,
        "stage": "agent_compile",
        "suggested_user_action": "revise_task",
        "support_debug_id": "api:4d0d8c18-3a06-4d53-9a57-2e5aa3f8c0cc:compile_unpublishable_output",
        "technical_reason": "Custom artifact publish gate failed: extract:quality_failed:singleton_endpoint_returned_collection",
        "user_facing_reason": "The compiled API did not pass runtime output verification."
      }
    }
  }
}
Use failure_reason_code for compact branching, failure.non_publishable_reason for the stable reason no API was published when one is available, and failure.artifact for support, billing, and retry decisions.
failure_reason_codeMeaningFix
captcha_blocked / rate_limitedThe target site blocked or throttled build-time access.Retry later for rate limits. For CAPTCHA or bot-wall blocks, revise toward a different public surface.
empty_html / non_html_contentThe URL did not provide usable page content for API generation.Try a different URL or revise toward a more specific public page.
auth_surfaces_no_loginThe requested data appears to require an authenticated session that this build could not compile.Revise toward public data, or use a supported session flow when available.
compile_unpublishable_outputPeel compiled a candidate artifact, but it did not pass the publishable API quality bar.Check failure.non_publishable_reason and failure.artifact.technical_reason, then revise with narrower instructions.
action_flow_incompletePeel found an action-flow candidate, but deterministic action endpoint publication is still gated.Revise toward a read-only public data task, or wait for action-flow support.
planner_no_plan / planner_blockedThe build-time planner could not produce a deterministic endpoint plan.Revise with clearer instructions or a more direct source URL.
flow_definition_invalidA generated deterministic flow was invalid before publication.Rebuild once. If it repeats, revise with a simpler task shape.
extraction_proof_failedThe generated endpoint failed final extraction proofing before publication.Revise with narrower fields or a more stable source page.
build_timeoutThe build exceeded its internal time budget.rebuild. If the target is slow to compile, raise timeout_ms on a fresh POST /v1/apis call, up to 120000.
build_cost_budget_exceededThe build exceeded the configured variable-cost budget before publication.Revise toward a narrower task or contact support for operator review.
unknownThe build failed before Peel could classify it into a more specific code.Contact support with the api_id and failure.artifact.support_debug_id.
failure.artifact.failure_class normalizes many lower-level codes into stable classes such as captcha_or_botwall, auth_required, unsupported_action, no_matching_data, compile_policy_violation, runtime_verification_failed, build_timeout, and internal_error. failure.artifact.billing_disposition tells you whether the build is not billable, needs refund review, or needs operator review. Action-flow gates keep publication closed until Peel has compiled a deterministic, policy-checked request sequence. These failures use failure.non_publishable_reason: "unsupported_action" and failure.artifact.failure_class: "unsupported_action". When the build reaches the custom artifact publish gate, Peel has already compiled a deterministic runtime artifact and is deciding whether it is safe to publish. These failures keep failure_reason_code: "compile_unpublishable_output" and usually normalize to failure.non_publishable_reason: "artifact_publishability_failed". Inspect failure.artifact.technical_reason and failure.artifact.support_debug_id for the precise operator diagnostic:
Technical reason fragmentMeaningFix
singleton_endpoint_returned_collectionA detail-style endpoint returned a collection-shaped payload, so Peel refused to publish a misleading runtime contract.Revise with collection-oriented instructions, or narrow the request to one entity/detail page.
endpoint_not_foundThe generated artifact did not contain the endpoint selected for publication.Rebuild. If it repeats, revise with a narrower endpoint name or task shape and include the support_debug_id when contacting support.
missing_field:<field>The deterministic artifact ran, but the sample output did not include a required task field.Revise with clearer field names or choose a URL where the requested field appears in the public evidence.
too_few_items_for_collection:<count>A collection endpoint produced fewer rows than the publish gate requires.Revise toward a broader listing page or rebuild if the source page changed.

Response envelope

All :call responses, successful or failed, share the same top-level envelope:
{
  "status": "success",
  "status_code": 200,
  "data": { },
  "error": null,
  "error_code": null,
  "execution_time": 842
}
On error:
{
  "status": "error",
  "status_code": 403,
  "data": null,
  "error": "Target responded with a CAPTCHA challenge",
  "error_code": "captcha_blocked",
  "execution_time": 1204
}
status_code inside the envelope mirrors the outer HTTP status so clients that only surface the body still have the code. For deterministic replay endpoints, upstream HTTP failures keep their target status and include structured upstream details in data instead of projecting through the endpoint output schema:
{
  "status": "error",
  "status_code": 429,
  "data": {
    "error": "Too Many Requests",
    "upstream_error_code": "429",
    "upstream_error_kind": "rate_limited",
    "upstream_status_code": 429
  },
  "error": null,
  "error_code": "upstream_error",
  "execution_time": 391
}
On failures where the transport succeeded but the parser could not extract structured data, the envelope also includes a raw_output field: a truncated preview of the upstream response body. Use it to debug extraction_failed and transport_error outcomes:
{
  "status": "error",
  "status_code": 422,
  "data": null,
  "error": "Extractor produced no rows for endpoint 'get_top_stories'",
  "error_code": "extraction_failed",
  "execution_time": 1547,
  "raw_output": "<!DOCTYPE html>\n<html><head><title>Maintenance</title></head>\n<body><h1>We'll be right back</h1><p>Scheduled maintenance, please try again in a few minutes.</p></bo…"
}
raw_output is always clipped and is not a substitute for a proper re-parse. When it appears consistently on a previously healthy endpoint, rebuild the API.

When an error means rebuild

Three signals usually point to rebuild as the right action:
  1. GET /v1/apis/{api_id}/health returns recommended_action: "rebuild".
  2. error_code is extraction_failed or endpoint_not_found on a previously healthy endpoint.
  3. Multiple endpoints on the same API start returning transport_error in a short window.
See API updates for the full decision tree.