Documentation Index
Fetch the complete documentation index at: https://skyvern.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
The SDK raises typed exceptions for API errors. In Python, all errors extend ApiError. In TypeScript, all errors extend SkyvernError. Both include the HTTP status code, response body, and headers.
Error types
| Exception | Status Code | When it’s raised |
|---|
BadRequestError | 400 | Invalid request parameters. |
ForbiddenError | 403 | Invalid or missing API key. |
NotFoundError | 404 | Resource (run, workflow, session) not found. |
ConflictError | 409 | Resource conflict (e.g., duplicate creation). |
UnprocessableEntityError | 422 | Request validation failed. |
ApiError (Python) / SkyvernError (TS) | Any | Base class for all API errors. Catch this as a fallback. |
SkyvernTimeoutError (TS only) | - | HTTP request timed out. |
Import errors from the package:
from skyvern.client.core import ApiError
from skyvern.client.errors import (
BadRequestError,
ForbiddenError,
NotFoundError,
ConflictError,
UnprocessableEntityError,
)
The specific Python error classes live in skyvern.client.errors. The base ApiError class lives in skyvern.client.core.
TypeScript: SkyvernError and SkyvernTimeoutError are top-level exports. The HTTP-specific errors (BadRequestError, etc.) extend SkyvernError and are accessed via the SkyvernApi namespace.
Catching errors
from skyvern import Skyvern
from skyvern.client.core import ApiError
from skyvern.client.errors import NotFoundError
client = Skyvern(api_key="YOUR_API_KEY")
try:
run = await client.get_run("tsk_nonexistent")
except NotFoundError as e:
print(f"Run not found: {e.body}")
except ApiError as e:
print(f"API error {e.status_code}: {e.body}")
Error properties
Every error has these attributes:
| Property (Python) | Property (TS) | Type | Description |
|---|
status_code | statusCode | int | None | HTTP status code. |
body | body | Any | Response body (usually a dict with error details). |
headers | - | dict[str, str] | None | Response headers. |
| - | rawResponse | RawResponse | undefined | The raw HTTP response (TS only). |
| - | message | string | Human-readable error message (TS only). |
Timeouts
Two different timeouts apply:
HTTP request timeout
Controls how long the SDK waits for the HTTP response from the Skyvern API. Set it in the constructor or per-request:
# Global timeout (applies to all requests)
client = Skyvern(api_key="YOUR_API_KEY", timeout=30.0)
# Per-request timeout
from skyvern.client.core import RequestOptions
result = await client.get_run(
"tsk_abc123",
request_options=RequestOptions(timeout_in_seconds=10),
)
When an HTTP request times out in TypeScript, a SkyvernTimeoutError is thrown.
Completion timeout
Controls how long wait_for_completion / waitForCompletion polls before giving up. This is separate from the HTTP timeout:
try:
result = await client.run_task(
prompt="Extract data",
url="https://example.com",
wait_for_completion=True,
timeout=300, # Give up after 5 minutes
)
except TimeoutError:
print("Task didn't complete in time")
The completion timeout raises Python’s built-in TimeoutError (via asyncio.timeout), not ApiError. In TypeScript, it throws a standard Error with a timeout message.
Retries
Configure automatic retries for transient failures. Set it in the constructor or per-request:
from skyvern.client.core import RequestOptions
result = await client.run_task(
prompt="Extract product data",
url="https://example.com/products",
request_options=RequestOptions(max_retries=3),
)
Retries apply to the HTTP request level (network errors, 5xx responses). They do not retry the entire task if it fails at the AI level - use get_run / getRun to check the status and re-run if needed.
Abort requests (TypeScript only)
Cancel in-flight requests using AbortSignal:
const controller = new AbortController();
// Cancel after 10 seconds
setTimeout(() => controller.abort(), 10000);
try {
const result = await skyvern.runTask(
{
body: {
prompt: "Extract data",
url: "https://example.com",
},
},
{ abortSignal: controller.signal },
);
} catch (e) {
if (e instanceof Error && e.name === "AbortError") {
console.log("Request was aborted");
}
}
Run failure vs API errors
There are two distinct failure modes:
API error - The HTTP request itself failed. The SDK raises an exception.
from skyvern.client.core import ApiError
try:
result = await client.run_task(prompt="...")
except ApiError as e:
print(f"API call failed: {e.status_code}")
Run failure - The API call succeeded, but the task/workflow failed during execution. No exception is raised. Check the status field:
result = await client.run_task(
prompt="Fill out the form",
url="https://example.com",
wait_for_completion=True,
)
if result.status == "failed":
print(f"Task failed: {result.failure_reason}")
elif result.status == "timed_out":
print(f"Task exceeded step limit after {result.step_count} steps")
elif result.status == "completed":
print(f"Success: {result.output}")
Run statuses
| Status | Description |
|---|
created | Run initialized, not yet queued. |
queued | Waiting for an available browser. |
running | AI is executing. |
completed | Finished successfully. |
failed | Encountered an error during execution. |
terminated | Manually stopped. |
timed_out | Exceeded step limit (max_steps). |
canceled | Canceled before starting. |