Skip to main content

Essentials

Errors and retries

Handle HTTP failures, browser task outcomes, AI Gateway error codes, stream errors, and safe retries.

Check the HTTP status before parsing a success response. Successful HTTP delivery and successful task execution are separate: a browser batch can return HTTP 200 with individual task failures, and a specification status request can return HTTP 200 with status: "failed".

HTTP errors

HTTPMeaningNext step
400Missing input, invalid ID, or an oversized browser batchCorrect the request
401Missing/invalid credentials, or the account cannot authenticate for this interfaceCheck the key and account access
402Insufficient credits or a subscription requirementRead the message and any actionUrl
403Access denied or specification trial exhaustedCheck account context and plan eligibility
404Resource missing or inaccessibleCheck the returned ID and the caller
429Rate limit or browser in-flight limit reachedBack off; inspect your queue
500Server-side failureInspect whether work was accepted before resubmitting
503Streaming capacity or website verification unavailableInspect code; retry DNS verification later, or use async submission for streaming capacity

General API errors usually include error and may include message. Browser submission gates use a machine-readable code:

{
  "error": "The submission would exceed your in-flight task limit.",
  "code": "QUEUE_FULL"
}
Browser codeHTTPHandling
INVALID_TASK400Correct the task object, instructions, or output schema
INVALID_URL400Provide a full HTTP(S) website URL
MISSING_INSTRUCTION400Add instructions or a non-empty output schema
URL_UNREACHABLE400Fix the domain; no DNS address was found
URL_CHECK_UNAVAILABLE503Retry later; no tasks were started or charged
BATCH_TOO_LARGE400Split the batch
SUBSCRIPTION_REQUIRED402Follow actionUrl to review plans
INSUFFICIENT_CREDITS402Follow actionUrl to add credits
QUEUE_FULL429Wait for tasks to finish or submit fewer tasks
RATE_LIMITED429Retry with exponential backoff and jitter

Input validation errors may include a zero-based taskIndex and a field. Validation rejects the whole batch before charging or starting work. Invalid tasks and explicit permanent URL/DNS failures are not retried in another sandbox; transient execution failures can still be retried.

These codes belong to Browser Agents. Do not assume an Architect 402 has a browser gate code.

AI Gateway errors

Errors from https://api.pre.dev/v1 use the OpenAI error shape with an extra predev object, so the OpenAI and Anthropic SDKs raise them as their usual typed exceptions.

{
  "error": {
    "message": "This pre.dev workspace has no credits left for AI calls. Top up at https://pre.dev/billing or enable auto-recharge.",
    "type": "insufficient_credits",
    "code": "insufficient_credits",
    "param": null,
    "predev": {
      "credits_remaining": 0,
      "estimated_credits": 1.4,
      "topup_url": "https://pre.dev/billing"
    }
  }
}
CodeHTTPCausepredev fieldsHandling
invalid_request400A speech request without model and input, or with a model that does not produce audioavailable_models for a wrong modelFix the request
missing_id400GET /v1/generation without idSend the generation id
missing_api_key401No Authorization or x-api-key headerSend the key; see authentication
invalid_api_key401Key unknown, or rotated more than 15 minutes agoCopy the current key from Integrations → Built-in
insufficient_credits402The balance cannot cover the call; nothing was sent to the modelcredits_remaining, estimated_credits, topup_urlAdd credits or enable auto-recharge
subscription_required402A Free workspace used its 5-credit gateway allowancecredits_remaining, trial_credits_used, topup_urlSubscribe
not_found404Unknown path, or a file, job, response, or generation that belongs to another workspace, including one a request refers to; nothing ran. On GET /v1/generation, also a call that recorded no stats (a failed call, for example) or a streamed call that is still runningCheck the path and id; look up a streamed call after its stream ends
not_ready404 or 502GET /v1/generation found the call, but its stats are not available yet (404) or could not be read (502)Retry in a few seconds
rate_limit_exceeded429More than the per-minute request limitretry_afterWait Retry-After seconds, then retry
too_many_auth_failures429Too many failed key attempts from one addressretry_afterCheck the key, then retry after a minute
internal_error500An unexpected gateway errorRetry, and quote x-predev-request-id if it persists
upstream_unavailable502The model did not answerRetry with backoff; consider models fallbacks
catalog_unavailable502 or 503The model catalog could not be read: 502 from the catalog listings, which carries no predev object, and 503 from GET /v1/models/publicRetry shortly
balance_unavailable503The balance check could not completeretry_afterWait Retry-After seconds, then retry

The error type follows the OpenAI convention for the status, for example authentication_error for 401 and rate_limit_error for 429; for 402 it repeats the code. A 429 also sets Retry-After. Rate limits lists the per-minute limits.

{
  "error": {
    "message": "The free trial includes 5 credits of AI calls and this workspace has used them. Subscribe at https://pre.dev/billing to keep going.",
    "type": "subscription_required",
    "code": "subscription_required",
    "param": null,
    "predev": {
      "credits_remaining": 18,
      "trial_credits_used": 5,
      "topup_url": "https://pre.dev/billing"
    }
  }
}

When the model rejects a request, for example an unknown model id, a malformed request, or an unsupported parameter, the error keeps its HTTP status and its message about the request, in the same OpenAI error shape. Check the model id against GET /v1/models first.

The OpenAI and Anthropic SDKs raise typed exceptions by status: AuthenticationError (401), RateLimitError (429), NotFoundError (404), and APIStatusError with the original status for 402, 502, and 503. Read error.code from the body to tell insufficient_credits from subscription_required, and x-predev-request-id from the response headers when reporting a problem.

import OpenAI from 'openai';

try {
  await client.chat.completions.create({ model: 'anthropic/claude-sonnet-5', messages });
} catch (error) {
  if (error instanceof OpenAI.APIError) {
    const code = (error.error as any)?.code;
    if (code === 'insufficient_credits') redirectTo((error.error as any).predev.topup_url);
    else if (error.status === 429) scheduleRetry(Number(error.headers?.get('retry-after') ?? 5));
    else throw error;
  }
}

Streaming failures

Once SSE response headers have been sent, a failure arrives as an event: error frame, even though the HTTP status is 200. The browser SDKs raise an exception for these frames. A disconnected stream or EOF without done does not establish success; fetch the run by its saved ID.

The existing-run stream’s done payload contains only the batch status. Fetch the final result after it. The submission stream’s done payload contains the full batch. See streaming.

AI Gateway streams that fail after headers are sent end early; the charge covers what the model generated. See gateway streaming.

Retry submissions

For REST browser requests, send a stable Idempotency-Key header. If a run with the same caller/key already exists from the last 24 hours, the API returns that run as JSON instead of creating a new one, even if the retry requested streaming. Keep the payload the same and use a new key for intentional new work. The API does not compare payloads for you.

Do not rely on this lookup as a lock for simultaneous duplicate requests. Serialize retries of the same logical submission.

Specification generation has no documented idempotency key. If a request times out, check history before generating again. A retry can create another specification and consume more credits.

SDK exceptions

Both predev-api SDKs provide AuthenticationError, RateLimitError, and PredevAPIError. Browser gate codes also map to SubscriptionRequiredError, InsufficientCreditsError, QueueFullError, and BatchTooLargeError. Billing exceptions may include actionUrl in Node or action_url in Python.

The Node base exception exposes message; Python exceptions can be read with str(error). Neither SDK exposes a statusCode / status_code property on its base exception. Use direct HTTP when your application needs the original status, headers, and full response body.

Was this page helpful?

On this page