API Reference

API Overview

Base URL, Bearer authentication, JSON request and error format, rate limits, HTTP status codes, and the full error code reference for the Thunderbit Open API.

Base URL

https://openapi.thunderbit.com/openapi/v1

Authentication

All endpoints use HTTP Bearer (API Key):

Authorization: Bearer YOUR_API_KEY

Format: tb_ followed by 32 hexadecimal characters (e.g., tb_a1b2c3d4e5f67890abcdef1234567890).

Get your key from the Thunderbit Dashboard. Keys are revocable and per-environment — never embed a production key in client-side code.

Error envelope

All error responses share the same envelope. By default (LEGACY format):

{
  "success": false,
  "error": {
    "code":    "INVALID_URL",
    "status":  400,
    "message": "The provided URL is not valid",
    "details": null
  }
}

Note: A GOOGLE_RPC alternate envelope was previously documented where code and status swapped types (string ↔ number). It is deprecated and not recommended — strongly-typed clients (OpenAPI codegen, Pydantic, serde, encoding/json) will fail to deserialize across the swap. Use the LEGACY format above; future updates keep code: string and status: number stable.

The details field may carry structured context — for example, field-level validation errors as { field: message } pairs returned on INVALID_PARAMETER.

Canonical error codes

HTTPCodeMeaning
400INVALID_URLURL format is invalid
400INVALID_SCHEMAJSON Schema is invalid
400INVALID_PARAMETEROne or more request parameters failed validation
400SCHEMA_OR_PROMPT_REQUIREDschema (or prompt) is required for extraction
400SCHEMA_AND_PROMPT_EXCLUSIVEschema and prompt cannot both be provided
400BATCH_SIZE_EXCEEDEDBatch request exceeds the 100-URL limit
400MALFORMED_REQUEST_BODYRequest body is not valid JSON
401API_KEY_MISSINGAuthorization header missing
401API_KEY_INVALID_FORMATAPI key format is invalid
401API_KEY_NOT_FOUNDAPI key not found in the system
401API_KEY_REVOKEDAPI key has been revoked
401API_KEY_DISABLEDAPI key has been disabled
401API_KEY_EXPIREDAPI key has expired
401INVALID_API_KEY(deprecated, use the specific API_KEY_* codes above)
402INSUFFICIENT_CREDITSNot enough credits on the account
404JOB_NOT_FOUNDBatch job not found
404RESOURCE_NOT_FOUNDGeneric resource not found
408REQUEST_TIMEOUTThe API request timed out
408SCRAPE_TIMEOUTThe target page took too long to respond
409JOB_ALREADY_COMPLETEDJob is already in a terminal state and cannot be cancelled or modified
422SCRAPE_SSL_ERRORTarget site has SSL/TLS problems
422SCRAPE_DNS_RESOLUTION_ERRORCannot resolve target hostname
422SCRAPE_SITE_ERRORTarget site returned an error
422SCRAPE_EMPTY_CONTENTTarget page returned empty content
422SCRAPE_CONTENT_TOO_LARGETarget page exceeds size limits
422SCRAPE_TARGET_FORBIDDENTarget site refused access (403)
422SCRAPE_TARGET_NOT_FOUNDTarget URL returned 404
422SCRAPE_UNSUPPORTED_FILETarget file type is not supported
429RATE_LIMIT_EXCEEDEDAccount rate limit triggered
429SCRAPE_TARGET_RATE_LIMITEDTarget site rate-limited our request
500INTERNAL_ERRORGeneric internal error
500DISTILL_FAILEDDistillation pipeline failed
500EXTRACT_FAILEDExtraction pipeline failed
500PIPELINE_ERRORPipeline step reported a failure
500AI_EXTRACTION_FAILEDAI extraction step failed
500MARKDOWN_CONVERSION_FAILEDHTML-to-Markdown conversion failed
502SCRAPE_SERVICE_FAILEDAll scraping providers failed
502UPSTREAM_BAD_GATEWAYUpstream returned an invalid response
503SCRAPE_SERVICE_UNAVAILABLEScraping provider is unavailable
503AI_SERVICE_UNAVAILABLEAI service is unavailable
503DOWNSTREAM_SERVICE_UNAVAILABLEA downstream service is temporarily unavailable
504UPSTREAM_TIMEOUTUpstream gateway timed out
504AI_TIMEOUTAI service call timed out

Retry strategy reference

Code classRetry?How
4xx (your input)❌ NoFix the request and try again
401 (auth)❌ NoRotate / re-issue API key
402 (credits)❌ NoTop up
408 / 504 (timeout)✅ YesExponential backoff, max 3 attempts
429 (rate-limited)✅ YesWait until X-RateLimit-Reset — see Rate Limits
5xx (server)✅ YesExponential backoff, max 3 attempts
SCRAPE_TARGET_* (target site)⚠️ MaybeRetry once with renderMode upgraded