--- title: Using Artifacts subtitle: Access recordings, screenshots, logs, and network data for every run description: Retrieve and inspect artifacts from Skyvern runs including browser recordings, screenshots, AI reasoning logs, DOM element trees, network HAR files, and Playwright traces to debug failures and unexpected results. slug: developers/debugging/using-artifacts keywords: - artifact - recording - screenshot - HAR file - Playwright trace - DOM tree - AI reasoning log - network data - generated code --- When a Skyvern run fails or produces unexpected results, artifacts are your debugging toolkit. Every run automatically captures what happened: recordings of the browser session, screenshots at each step, the AI's reasoning, and network traffic. This page covers how to retrieve artifacts and what each type tells you. Looking for a specific artifact type? Jump to the [artifact types reference](#artifact-types-reference) to see all available types, then come back here to learn how to retrieve them. --- ## Before you start You need a `run_id` to retrieve artifacts. You get this when you [run a task](/running-automations/run-a-task) or workflow. --- ## Retrieve artifacts Use `get_run_artifacts` with the `run_id` from your task or workflow run: ```python Python import os from skyvern import Skyvern client = Skyvern(api_key=os.getenv("SKYVERN_API_KEY")) artifacts = await client.get_run_artifacts(run_id) for artifact in artifacts: print(f"{artifact.artifact_type}: {artifact.signed_url}") ``` ```typescript TypeScript import { SkyvernClient } from "@skyvern/client"; const client = new SkyvernClient({ apiKey: process.env.SKYVERN_API_KEY, }); const artifacts = await client.getRunArtifacts(runId); for (const artifact of artifacts) { console.log(`${artifact.artifact_type}: ${artifact.signed_url}`); } ``` ```bash cURL curl -X GET "https://api.skyvern.com/v1/runs/$RUN_ID/artifacts" \ -H "x-api-key: $SKYVERN_API_KEY" ``` Signed URLs expire after 24 hours. If a URL has expired, call `get_run_artifacts` again to get fresh URLs. When running Skyvern locally, `signed_url` will be `null`. Access artifacts directly from your local file system instead. --- ## Filter by artifact type To get only specific artifact types, pass `artifact_type`: ```python Python # Get only recordings and final screenshots artifacts = await client.get_run_artifacts( run_id, artifact_type=["recording", "screenshot_final"] ) ``` ```typescript TypeScript const artifacts = await client.getRunArtifacts(runId, { artifact_type: ["recording", "screenshot_final"], }); ``` ```bash cURL curl -X GET "https://api.skyvern.com/v1/runs/$RUN_ID/artifacts?artifact_type=recording&artifact_type=screenshot_final" \ -H "x-api-key: $SKYVERN_API_KEY" ``` --- ## Artifact types reference ### Visual artifacts These show you what the browser looked like at various points. | Type | What it contains | Use this to | |------|------------------|-------------| | `recording` | Full video of the browser session (WebM) | Watch the entire run, see exactly what happened | | `screenshot` | Base screenshot capture | General page state capture | | `screenshot_final` | Screenshot when the run ended | Check the final state (did it end on the right page?) | | `screenshot_action` | Screenshot taken after each action | See the page state after each click, type, or navigation | | `screenshot_llm` | Screenshot sent to the LLM for decision-making | Understand what the AI "saw" when it made each decision | **Debugging tip:** If the run failed, start with `screenshot_final` to see where it stopped, then watch the `recording` to see how it got there. ### AI reasoning artifacts These show you why the AI made each decision. | Type | What it contains | Use this to | |------|------------------|-------------| | `llm_prompt` | The prompt sent to the LLM | See exactly what instructions the AI received | | `llm_request` | Full request including context | Check if the right context was included | | `llm_response` | Raw LLM response | See the AI's unprocessed output | | `llm_response_parsed` | Parsed response (extracted actions) | Understand what actions the AI decided to take | | `llm_response_rendered` | Parsed response with real URLs | Debug URL targeting issues (see below) | **Debugging tip:** If the AI did something unexpected, check `llm_prompt` to see if your prompt was interpreted correctly, then `llm_response_parsed` to see what action it extracted. **About `llm_response_rendered`:** Skyvern hashes URLs before sending them to the LLM to reduce token usage and avoid confusing the model with long query strings. The `llm_response_parsed` artifact contains these hashed placeholders (like `{{_a1b2c3}}`), while `llm_response_rendered` shows the same response with actual URLs substituted back in. Use this when you need to verify which exact URL the AI targeted. ### Page structure artifacts These show how Skyvern interpreted the page. | Type | What it contains | Use this to | |------|------------------|-------------| | `visible_elements_tree` | DOM tree of visible elements (JSON) | See which elements Skyvern detected | | `visible_elements_tree_trimmed` | Trimmed tree (sent to LLM) | See what the AI could "see" | | `visible_elements_tree_in_prompt` | Element tree as plain text | Read exactly what was embedded in the prompt | | `visible_elements_id_css_map` | CSS selectors for each element | Debug element targeting issues | | `visible_elements_id_frame_map` | Element-to-iframe mapping | Debug elements inside iframes | | `visible_elements_id_xpath_map` | XPath selectors for each element | Alternative element targeting debug | | `hashed_href_map` | Mapping of hashed URLs to original URLs | Decode URL placeholders in LLM responses | | `html` | Generic HTML capture | Inspect page HTML | | `html_scrape` | Full HTML captured during scraping | Inspect the raw page structure | | `html_action` | HTML captured after an action | See how the page changed after each action | **Debugging tip:** If the AI couldn't find an element, check `visible_elements_tree` to see if it was detected. If not, the element might be in an iframe, dynamically loaded, or outside the viewport. **About the element tree variants:** The `visible_elements_tree` is a JSON structure, while `visible_elements_tree_in_prompt` is the plain-text representation that gets embedded directly into the LLM prompt. The latter is often easier to read when debugging prompt issues. If you're debugging iframe-related problems, `visible_elements_id_frame_map` shows which frame contains each element ID. ### Log artifacts These contain structured execution data. | Type | What it contains | Use this to | |------|------------------|-------------| | `skyvern_log` | Formatted execution logs | Read through the run step-by-step | | `skyvern_log_raw` | Raw JSON logs | Parse programmatically for automation | | `browser_console_log` | Browser console output | Debug JavaScript errors on the page | **Debugging tip:** `skyvern_log` is human-readable and shows the flow of execution. Start here for an overview before diving into specific artifacts. ### Network artifacts | Type | What it contains | Use this to | |------|------------------|-------------| | `har` | HTTP Archive (network requests/responses) | Debug API calls, check for failed requests, see response data | | `trace` | Playwright trace file | Replay the session in Playwright Trace Viewer | **Debugging tip:** The HAR file captures every network request. If a form submission failed, check the HAR to see if the request was sent and what the server responded. ### File artifacts | Type | What it contains | Use this to | |------|------------------|-------------| | `script_file` | Generated Playwright scripts | See the code Skyvern would use to repeat this task | --- ## Artifact response fields | Field | Type | Description | |-------|------|-------------| | `artifact_id` | string | Unique identifier | | `artifact_type` | string | Type (see tables above) | | `uri` | string | Internal storage path | | `signed_url` | string \| null | Pre-signed URL for downloading | | `task_id` | string \| null | Associated task ID | | `step_id` | string \| null | Associated step ID | | `run_id` | string \| null | Run ID (e.g., `tsk_v2_...`, `wr_...`) | | `workflow_run_id` | string \| null | Workflow run ID | | `workflow_run_block_id` | string \| null | Workflow block ID | | `organization_id` | string | Your organization | | `created_at` | datetime | When created | | `modified_at` | datetime | When modified | --- ## Next steps Common issues and how to fix them Map errors to custom codes for programmatic handling