Skip to main content
TinyFish surfaces errors in two layers, and you need to handle both:
  1. API-level errors — returned as non-2xx HTTP responses (auth, validation, rate limits, server errors).
  2. Run-response error codes — returned with HTTP 200 inside the error object of a run response (agent failures, infrastructure issues that map to a finished run, cancellations).
Knowing which layer you’re looking at tells you whether the issue is with the request, your account, or the automation itself.

Error Response Format

API-level errors use one of two schemas depending on the HTTP status code:
Schema-wise details is optional on every error response. In practice only INVALID_INPUT (400) populates it. The details array contains Zod validation issues — each issue has at minimum code, path, and message, plus issue-specific fields like expected (invalid_type) or values (invalid_value).
/v1/automation/run-batch uses a per-run error envelope instead of the top-level shape above. See Batch Errors below.

API-level Error Codes

MISSING_API_KEY

HTTP Status: 401 The X-API-Key header was not included in the request.
Solution: Add the X-API-Key header to your request:

INVALID_API_KEY

HTTP Status: 401 The provided API key does not exist or has been revoked.
Solutions:
  1. Verify your API key is correct (no extra whitespace)
  2. Check if the key was deleted in the API Keys dashboard
  3. Generate a new key if needed

UNAUTHORIZED

HTTP Status: 401 Authentication failed for a reason other than missing/invalid key. Typical cases: an upstream service (e.g. Vault) connection expired, or required user context is missing.
Solutions:
  1. Check your account status at agent.tinyfish.ai/api-keys
  2. For Vault-related calls, reconnect your vault under Settings → Vault
  3. Try generating a new API key

INVALID_INPUT

HTTP Status: 400 The request body failed validation.
Common Causes:
  • url is missing or not a valid URL (must include https://)
  • goal is empty or missing
  • browser_profile is not "lite" or "stealth"
  • proxy_config.country_code is not a supported 2-letter code (US, GB, CA, DE, FR, JP, AU)
  • output_schema is invalid JSON Schema
  • Missing required query parameter (e.g. query on /v1/search)
Solution: Check the details field for specific validation errors. Each entry includes the failing field path and a human-readable message.

FORBIDDEN

HTTP Status: 403 Authentication succeeded, but the request was rejected — usually because the account lacks an entitlement, capability, or remaining credits.
Common Causes:
  • No remaining credits or expired subscription (returned as FORBIDDEN at request time; runs that get accepted and then fail on billing surface INSUFFICIENT_CREDITS inside the run response)
  • proxy_config.type: "custom" requested without the custom-proxy entitlement
  • output_schema provided without the output-schema entitlement
  • capture_config requests a capability the account isn’t enabled for
  • Content blocked by policy (see also CONTENT_POLICY_VIOLATION on run responses)
  • Attempting to access a resource you don’t own
Solution: Check your account balance and subscription at agent.tinyfish.ai/api-keys, or contact support to enable a specific capability. The message field always specifies which entitlement or condition failed.

NOT_FOUND

HTTP Status: 404 The requested resource does not exist.
Common Causes:
  • Invalid run_id in GET /v1/runs/:id
  • Vault connection not found
  • Browser context profile not found
  • Step HTML/screenshot not found (GET /v1/runs/:id/steps/:stepId/...)
  • Run was deleted or never existed
  • Run ID belongs to a different token scope — CLI/REST run IDs and MCP run IDs live in separate scopes, so a CLI lookup for an MCP-created run returns 404 by design
Solution: Verify the resource ID is correct. Run IDs are returned from /v1/automation/run-async or can be listed via GET /v1/runs.

RETRY_REQUIRED

HTTP Status: 409 A transient conflict prevented the request from completing. Currently emitted by Browser Context Profile setup endpoints (/v1/profiles/:id/save, /v1/profiles/:id/setup-session, /v1/profiles/:id/setup-session/cancel) when the setup session is in an intermediate state.
Solution: Wait briefly and retry. Use a short delay (1–2s) plus exponential backoff if the conflict persists.

RATE_LIMIT_EXCEEDED

HTTP Status: 429 Too many requests in a short period.
Rate limits depend on your active plan and which API you’re calling:
  • /v1/search and /v1/fetch enforce per-minute request limits tied to your subscription.
  • /v1/automation/run, /run-async, and /run-batch enforce a pending-run cap tied to your subscription’s concurrency limit.
See your plan for the specific numbers, or contact support if you need higher limits. Response headers:
The automation pending-run cap (429 from /v1/automation/run, /run-async, /run-batch) does not set Retry-After or X-RateLimit-Limit — wait for existing runs to finish and retry. The body message includes your current count and the maximum.
Solutions:
  1. Respect Retry-After when present, otherwise implement exponential backoff
  2. Space out requests (recommended: 1-2 seconds between calls)
  3. Use batch endpoints for high-volume workloads
  4. Contact support for higher rate limits
Example: Exponential Backoff

INTERNAL_ERROR

HTTP Status: 500 An unexpected error occurred on the server.
Solutions:
  1. Retry the request after a brief delay
  2. If the error persists, check agent.tinyfish.ai/status for outages
  3. Contact support with your request details and timestamp (include X-Request-ID if you have it)

Run-response Error Codes

Once a run is accepted, completion-time failures are reported inside the run response body — not as HTTP error codes. The HTTP response is 200, and you inspect status + error:
The category field gives you a quick branching key: Optional fields:
  • retry_after — suggested delay in seconds (null if not retryable)
  • help_url — link to troubleshooting docs
  • help_message — short human-readable guidance

SERVICE_BUSY

Category: SYSTEM_FAILURE · In-body HTTP: 200 The platform is temporarily out of capacity (browser pool exhausted, dependent service unavailable). Equivalent to a 503 if returned at the HTTP layer. Solution: Retry with exponential backoff.

TIMEOUT

Category: SYSTEM_FAILURE · In-body HTTP: 200 An infrastructure or request timeout terminated the run. Equivalent to a 504. Solution: Retry. If the goal is large/multi-step, consider splitting it or simplifying.

INSUFFICIENT_CREDITS

Category: BILLING_FAILURE · In-body HTTP: 200 The run was terminated mid-flight because the account ran out of credits. (Pre-flight credit failures surface as FORBIDDEN at the HTTP layer instead.) Solution: Add credits at agent.tinyfish.ai/api-keys, then retry.

CONTENT_POLICY_VIOLATION

Category: AGENT_FAILURE · In-body HTTP: 200 The request — typically the goal text or a target URL — was blocked by content policy. Solution: Adjust the goal or target. Contact support if you believe the block was a false positive.

MAX_STEPS_EXCEEDED

Category: AGENT_FAILURE · In-body HTTP: 200 The automation hit the configured maximum step count without producing a result. Solution: Simplify the goal, split it into multiple runs, or raise the step limit if your plan supports it.

SITE_BLOCKED

Category: AGENT_FAILURE · In-body HTTP: 200 The target site blocked the automation (anti-bot, CAPTCHA, IP block). The status field is still FAILED. Solution: Switch browser_profile to "stealth", attach a proxy via proxy_config, or use a Browser Context Profile with a warmed session. See the anti-bot guide.

TASK_FAILED

Category: AGENT_FAILURE · In-body HTTP: 200 The agent ran but couldn’t achieve the goal — navigation failed, content not found, authentication required, the result was incorrect, or the task wasn’t achievable as described. Solution: Make the goal more concrete (which page, which selector-equivalent description, which field). See the prompting guide. For auth flows, use a vault credential or a saved profile.

CANCELLED

Category: N/A · Status: CANCELLED · In-body HTTP: 200 The run was cancelled — either by you (POST /v1/runs/:id/cancel), by SDK cancellation, or because the async task lifecycle was terminated. Not an error in the usual sense. Solution: No action needed unless the cancellation was unintended.

Batch Errors

/v1/automation/run-batch validates the whole request first, then dispatches each child run. Batch-level failures (auth, missing capability, validation) follow the standard { "error": { "code", "message" } } shape. Per-run dispatch errors are returned inside the batch response under each run’s slot. Treat the batch envelope as “did the batch get accepted?” and inspect each child for “did the individual run get scheduled?”

Run Status vs Error Codes

HTTP error codes (the table below) indicate request-level failures — your request didn’t make it to the agent. Run-response error codes indicate completion-level outcomes — the run reached the worker and reported back.For more on COMPLETED-but-failed runs, see Understanding Run Status.

HTTP Status Code Summary

Authentication

API key setup and troubleshooting

FAQ

Common questions and issues