Add Mintlify documentation setup (#4516)
Co-authored-by: Suchintan <suchintan@users.noreply.github.com>
This commit is contained in:
815
docs/running-automations/extract-structured-data.mdx
Normal file
815
docs/running-automations/extract-structured-data.mdx
Normal file
@@ -0,0 +1,815 @@
|
||||
---
|
||||
title: Extract Structured Data
|
||||
subtitle: Get consistent, typed output from your tasks
|
||||
slug: running-automations/extract-structured-data
|
||||
---
|
||||
|
||||
export const FIELD_TYPES = [
|
||||
{ value: "string", label: "String" },
|
||||
{ value: "number", label: "Number" },
|
||||
{ value: "integer", label: "Integer" },
|
||||
{ value: "boolean", label: "Boolean" },
|
||||
]
|
||||
|
||||
export const SchemaBuilder = () => {
|
||||
const [schemaType, setSchemaType] = useState("single")
|
||||
const [arrayName, setArrayName] = useState("items")
|
||||
const [fields, setFields] = useState([
|
||||
{ id: "1", name: "title", type: "string", description: "The title" },
|
||||
])
|
||||
const [outputFormat, setOutputFormat] = useState("python")
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const addField = () => {
|
||||
setFields([...fields, { id: String(Date.now()), name: "", type: "string", description: "" }])
|
||||
}
|
||||
|
||||
const removeField = (id) => {
|
||||
if (fields.length > 1) setFields(fields.filter((f) => f.id !== id))
|
||||
}
|
||||
|
||||
const updateField = (id, key, value) => {
|
||||
setFields(fields.map((f) => (f.id === id ? { ...f, [key]: value } : f)))
|
||||
}
|
||||
|
||||
// Track duplicate field names
|
||||
const duplicateNames = useMemo(() => {
|
||||
const names = fields.map((f) => f.name).filter((n) => n.trim() !== "")
|
||||
const counts = {}
|
||||
names.forEach((n) => { counts[n] = (counts[n] || 0) + 1 })
|
||||
return new Set(Object.keys(counts).filter((n) => counts[n] > 1))
|
||||
}, [fields])
|
||||
|
||||
const schema = useMemo(() => {
|
||||
const properties = {}
|
||||
fields.forEach((field) => {
|
||||
if (field.name) {
|
||||
properties[field.name] = {
|
||||
type: field.type,
|
||||
description: field.description || `The ${field.name}`,
|
||||
}
|
||||
}
|
||||
})
|
||||
if (schemaType === "array") {
|
||||
return {
|
||||
type: "object",
|
||||
properties: {
|
||||
[arrayName]: {
|
||||
type: "array",
|
||||
description: "List of extracted items",
|
||||
items: { type: "object", properties },
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return { type: "object", properties }
|
||||
}, [fields, schemaType, arrayName])
|
||||
|
||||
const formattedOutput = useMemo(() => {
|
||||
const jsonStr = JSON.stringify(schema, null, 2)
|
||||
if (outputFormat === "python") {
|
||||
// Only replace JSON literals at value positions (after ": "), not inside quoted strings
|
||||
return `data_extraction_schema=${jsonStr.replace(/: null/g, ": None").replace(/: true/g, ": True").replace(/: false/g, ": False")}`
|
||||
}
|
||||
if (outputFormat === "typescript") {
|
||||
return `data_extraction_schema: ${jsonStr}`
|
||||
}
|
||||
return `"data_extraction_schema": ${jsonStr}`
|
||||
}, [schema, outputFormat])
|
||||
|
||||
const copyToClipboard = async () => {
|
||||
await navigator.clipboard.writeText(formattedOutput)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-5 border rounded-lg mt-4 mb-4 not-prose" style={{ backgroundColor: "#f8fafc" }}>
|
||||
<div className="mb-5">
|
||||
<label className="block font-semibold mb-2 text-sm">What are you extracting?</label>
|
||||
<div className="flex gap-3">
|
||||
{[
|
||||
{ value: "single", label: "Single object", desc: "Extract one item with multiple fields" },
|
||||
{ value: "array", label: "List of items", desc: "Extract multiple items with the same structure" },
|
||||
].map((type) => (
|
||||
<button
|
||||
key={type.value}
|
||||
onClick={() => setSchemaType(type.value)}
|
||||
className={`flex-1 p-3 rounded-md text-left border-2 ${schemaType === type.value ? "border-indigo-500 bg-indigo-50" : "border-gray-200 bg-white"}`}
|
||||
>
|
||||
<div className="font-medium text-sm">{type.label}</div>
|
||||
<div className="text-xs text-gray-500 mt-1">{type.desc}</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{schemaType === "array" && (
|
||||
<div className="mb-5">
|
||||
<label className="block text-xs font-medium mb-1 text-gray-700">Array field name</label>
|
||||
<input
|
||||
type="text"
|
||||
value={arrayName}
|
||||
onChange={(e) => setArrayName(e.target.value)}
|
||||
className="w-full p-2 border rounded-md text-sm"
|
||||
placeholder="items"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-4">
|
||||
<label className="block font-semibold mb-2 text-sm">Fields to extract</label>
|
||||
<div className="flex flex-col gap-2">
|
||||
{fields.map((field) => (
|
||||
<div key={field.id} className="flex gap-2 items-center p-3 bg-white rounded-md border">
|
||||
<input
|
||||
type="text"
|
||||
value={field.name}
|
||||
onChange={(e) => updateField(field.id, "name", e.target.value)}
|
||||
placeholder="Field name"
|
||||
className={`w-32 p-2 border rounded-md text-sm ${duplicateNames.has(field.name) ? "border-red-500 bg-red-50" : ""}`}
|
||||
title={duplicateNames.has(field.name) ? "Duplicate field name - will be overwritten in schema" : ""}
|
||||
/>
|
||||
<select
|
||||
value={field.type}
|
||||
onChange={(e) => updateField(field.id, "type", e.target.value)}
|
||||
className="w-24 p-2 border rounded-md text-sm bg-white"
|
||||
>
|
||||
{FIELD_TYPES.map((t) => (
|
||||
<option key={t.value} value={t.value}>{t.label}</option>
|
||||
))}
|
||||
</select>
|
||||
<input
|
||||
type="text"
|
||||
value={field.description}
|
||||
onChange={(e) => updateField(field.id, "description", e.target.value)}
|
||||
placeholder="Description (helps AI understand what to extract)"
|
||||
className="flex-1 p-2 border rounded-md text-sm"
|
||||
/>
|
||||
<button
|
||||
onClick={() => removeField(field.id)}
|
||||
disabled={fields.length === 1}
|
||||
className={`px-2 py-1 rounded text-lg ${fields.length === 1 ? "text-gray-300 cursor-not-allowed" : "text-red-500 hover:bg-red-50"}`}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button onClick={addField} className="w-full mt-2 p-2 border border-dashed rounded-md text-gray-500 text-sm hover:bg-gray-50">
|
||||
+ Add field
|
||||
</button>
|
||||
{duplicateNames.size > 0 && (
|
||||
<div className="mt-2 p-2 bg-red-50 border border-red-200 rounded-md text-red-700 text-xs">
|
||||
Duplicate field names detected. Only the last field with each name will appear in the schema.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<label className="font-semibold text-sm">Generated schema</label>
|
||||
<div className="flex gap-1">
|
||||
{["python", "typescript", "curl"].map((format) => (
|
||||
<button
|
||||
key={format}
|
||||
onClick={() => setOutputFormat(format)}
|
||||
className={`px-3 py-1 rounded text-xs ${outputFormat === format ? "bg-indigo-100 border-indigo-500 border font-medium" : "bg-white border border-gray-200"}`}
|
||||
>
|
||||
{format === "curl" ? "cURL" : format.charAt(0).toUpperCase() + format.slice(1)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<pre className="bg-slate-800 text-slate-200 p-4 rounded-md overflow-auto text-xs leading-relaxed">
|
||||
<code>{formattedOutput}</code>
|
||||
</pre>
|
||||
<button
|
||||
onClick={copyToClipboard}
|
||||
className={`absolute top-2 right-2 px-3 py-1 rounded text-xs text-white ${copied ? "bg-green-500" : "bg-slate-600 hover:bg-slate-500"}`}
|
||||
>
|
||||
{copied ? "Copied!" : "Copy"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
By default, Skyvern returns extracted data in whatever format makes sense for the task.
|
||||
Pass a `data_extraction_schema` to enforce a specific structure using [JSON Schema.](https://json-schema.org/)
|
||||
|
||||
---
|
||||
|
||||
## Define a schema
|
||||
|
||||
Add `data_extraction_schema` parameter to your task with a JSON Schema object:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the title of the top post",
|
||||
url="https://news.ycombinator.com",
|
||||
data_extraction_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The title of the top post"
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the title of the top post",
|
||||
url: "https://news.ycombinator.com",
|
||||
data_extraction_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: {
|
||||
type: "string",
|
||||
description: "The title of the top post",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the title of the top post",
|
||||
"url": "https://news.ycombinator.com",
|
||||
"data_extraction_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The title of the top post"
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The `description` field in each property helps Skyvern understand what data to extract. Be specific.
|
||||
|
||||
<Warning>
|
||||
`description` fields drive extraction quality. Vague descriptions like "the data" produce vague results. Be specific: "The product price in USD, without currency symbol."
|
||||
</Warning>
|
||||
|
||||
---
|
||||
|
||||
## Schema format
|
||||
|
||||
Skyvern uses standard JSON Schema. Common types:
|
||||
|
||||
| Type | JSON Schema | Example value |
|
||||
|------|-------------|---------------|
|
||||
| String | `{"type": "string"}` | `"Hello world"` |
|
||||
| Number | `{"type": "number"}` | `19.99` |
|
||||
| Integer | `{"type": "integer"}` | `42` |
|
||||
| Boolean | `{"type": "boolean"}` | `true` |
|
||||
| Array | `{"type": "array", "items": {...}}` | `[1, 2, 3]` |
|
||||
| Object | `{"type": "object", "properties": {...}}` | `{"key": "value"}` |
|
||||
|
||||
<Note>
|
||||
A schema doesn't guarantee all fields are populated. If the data isn't on the page, fields return `null`. Design your code to handle missing values.
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Build your schema
|
||||
|
||||
Use the interactive builder below to generate a schema, then copy it into your code.
|
||||
|
||||
<SchemaBuilder />
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Single value
|
||||
|
||||
Extract one piece of information, such as the current price of Bitcoin:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the current Bitcoin price in USD",
|
||||
url="https://coinmarketcap.com/currencies/bitcoin/",
|
||||
data_extraction_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"price": {
|
||||
"type": "number",
|
||||
"description": "Current Bitcoin price in USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the current Bitcoin price in USD",
|
||||
url: "https://coinmarketcap.com/currencies/bitcoin/",
|
||||
data_extraction_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
price: {
|
||||
type: "number",
|
||||
description: "Current Bitcoin price in USD",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the current Bitcoin price in USD",
|
||||
"url": "https://coinmarketcap.com/currencies/bitcoin/",
|
||||
"data_extraction_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"price": {
|
||||
"type": "number",
|
||||
"description": "Current Bitcoin price in USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Output (when completed):**
|
||||
|
||||
```json
|
||||
{
|
||||
"price": 104521.37
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### List of items
|
||||
|
||||
Extract multiple items with the same structure, such as the top posts from a news site:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the top 5 posts",
|
||||
url="https://news.ycombinator.com",
|
||||
data_extraction_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"posts": {
|
||||
"type": "array",
|
||||
"description": "Top 5 posts from the front page",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Post title"
|
||||
},
|
||||
"points": {
|
||||
"type": "integer",
|
||||
"description": "Number of points"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Link to the post"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the top 5 posts",
|
||||
url: "https://news.ycombinator.com",
|
||||
data_extraction_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
posts: {
|
||||
type: "array",
|
||||
description: "Top 5 posts from the front page",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: {
|
||||
type: "string",
|
||||
description: "Post title",
|
||||
},
|
||||
points: {
|
||||
type: "integer",
|
||||
description: "Number of points",
|
||||
},
|
||||
url: {
|
||||
type: "string",
|
||||
description: "Link to the post",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the top 5 posts",
|
||||
"url": "https://news.ycombinator.com",
|
||||
"data_extraction_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"posts": {
|
||||
"type": "array",
|
||||
"description": "Top 5 posts from the front page",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Post title"
|
||||
},
|
||||
"points": {
|
||||
"type": "integer",
|
||||
"description": "Number of points"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Link to the post"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Output (when completed):**
|
||||
|
||||
```json
|
||||
{
|
||||
"posts": [
|
||||
{
|
||||
"title": "Running Claude Code dangerously (safely)",
|
||||
"points": 342,
|
||||
"url": "https://blog.emilburzo.com/2026/01/running-claude-code-dangerously-safely/"
|
||||
},
|
||||
{
|
||||
"title": "Linux kernel framework for PCIe device emulation",
|
||||
"points": 287,
|
||||
"url": "https://github.com/cakehonolulu/pciem"
|
||||
},
|
||||
{
|
||||
"title": "I'm addicted to being useful",
|
||||
"points": 256,
|
||||
"url": "https://www.seangoedecke.com/addicted-to-being-useful/"
|
||||
},
|
||||
{
|
||||
"title": "Level S4 solar radiation event",
|
||||
"points": 198,
|
||||
"url": "https://www.swpc.noaa.gov/news/g4-severe-geomagnetic-storm"
|
||||
},
|
||||
{
|
||||
"title": "WebAssembly Text Format parser performance",
|
||||
"points": 176,
|
||||
"url": "https://blog.gplane.win/posts/improve-wat-parser-perf.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<Tip>
|
||||
Arrays without limits extract everything visible on the page. Specify limits in your prompt (e.g., "top 5 posts") or the array description to control output size.
|
||||
</Tip>
|
||||
|
||||
---
|
||||
|
||||
### Nested objects
|
||||
|
||||
Extract hierarchical data, such as a product with its pricing and availability:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get product details including pricing and availability",
|
||||
url="https://www.amazon.com/dp/B0EXAMPLE",
|
||||
data_extraction_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product": {
|
||||
"type": "object",
|
||||
"description": "Product information",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Product name"
|
||||
},
|
||||
"pricing": {
|
||||
"type": "object",
|
||||
"description": "Pricing details",
|
||||
"properties": {
|
||||
"current_price": {
|
||||
"type": "number",
|
||||
"description": "Current price in USD"
|
||||
},
|
||||
"original_price": {
|
||||
"type": "number",
|
||||
"description": "Original price before discount"
|
||||
},
|
||||
"discount_percent": {
|
||||
"type": "integer",
|
||||
"description": "Discount percentage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"availability": {
|
||||
"type": "object",
|
||||
"description": "Stock information",
|
||||
"properties": {
|
||||
"in_stock": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the item is in stock"
|
||||
},
|
||||
"delivery_estimate": {
|
||||
"type": "string",
|
||||
"description": "Estimated delivery date"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get product details including pricing and availability",
|
||||
url: "https://www.amazon.com/dp/B0EXAMPLE",
|
||||
data_extraction_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
product: {
|
||||
type: "object",
|
||||
description: "Product information",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
description: "Product name",
|
||||
},
|
||||
pricing: {
|
||||
type: "object",
|
||||
description: "Pricing details",
|
||||
properties: {
|
||||
current_price: {
|
||||
type: "number",
|
||||
description: "Current price in USD",
|
||||
},
|
||||
original_price: {
|
||||
type: "number",
|
||||
description: "Original price before discount",
|
||||
},
|
||||
discount_percent: {
|
||||
type: "integer",
|
||||
description: "Discount percentage",
|
||||
},
|
||||
},
|
||||
},
|
||||
availability: {
|
||||
type: "object",
|
||||
description: "Stock information",
|
||||
properties: {
|
||||
in_stock: {
|
||||
type: "boolean",
|
||||
description: "Whether the item is in stock",
|
||||
},
|
||||
delivery_estimate: {
|
||||
type: "string",
|
||||
description: "Estimated delivery date",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get product details including pricing and availability",
|
||||
"url": "https://www.amazon.com/dp/B0EXAMPLE",
|
||||
"data_extraction_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product": {
|
||||
"type": "object",
|
||||
"description": "Product information",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Product name"
|
||||
},
|
||||
"pricing": {
|
||||
"type": "object",
|
||||
"description": "Pricing details",
|
||||
"properties": {
|
||||
"current_price": {
|
||||
"type": "number",
|
||||
"description": "Current price in USD"
|
||||
},
|
||||
"original_price": {
|
||||
"type": "number",
|
||||
"description": "Original price before discount"
|
||||
},
|
||||
"discount_percent": {
|
||||
"type": "integer",
|
||||
"description": "Discount percentage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"availability": {
|
||||
"type": "object",
|
||||
"description": "Stock information",
|
||||
"properties": {
|
||||
"in_stock": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the item is in stock"
|
||||
},
|
||||
"delivery_estimate": {
|
||||
"type": "string",
|
||||
"description": "Estimated delivery date"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Output (when completed):**
|
||||
|
||||
```json
|
||||
{
|
||||
"product": {
|
||||
"name": "Wireless Bluetooth Headphones",
|
||||
"pricing": {
|
||||
"current_price": 79.99,
|
||||
"original_price": 129.99,
|
||||
"discount_percent": 38
|
||||
},
|
||||
"availability": {
|
||||
"in_stock": true,
|
||||
"delivery_estimate": "Tomorrow, Jan 21"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessing extracted data
|
||||
|
||||
The extracted data appears in the `output` field of the completed run. Poll until the task reaches a terminal state, then access the output.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the top post",
|
||||
url="https://news.ycombinator.com",
|
||||
data_extraction_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {"type": "string", "description": "Post title"},
|
||||
"points": {"type": "integer", "description": "Points"}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
run_id = result.run_id
|
||||
|
||||
while True:
|
||||
run = await client.get_run(run_id)
|
||||
|
||||
if run.status in ["completed", "failed", "terminated", "timed_out", "canceled"]:
|
||||
break
|
||||
|
||||
await asyncio.sleep(5)
|
||||
|
||||
# Access the extracted data
|
||||
print(f"Output: {run.output}")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the top post",
|
||||
url: "https://news.ycombinator.com",
|
||||
data_extraction_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: { type: "string", description: "Post title" },
|
||||
points: { type: "integer", description: "Points" },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const runId = result.run_id;
|
||||
|
||||
while (true) {
|
||||
const run = await client.getRun(runId);
|
||||
|
||||
if (["completed", "failed", "terminated", "timed_out", "canceled"].includes(run.status)) {
|
||||
console.log(`Output: ${JSON.stringify(run.output)}`);
|
||||
break;
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
}
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
RUN_ID="your_run_id_here"
|
||||
|
||||
while true; do
|
||||
RESPONSE=$(curl -s -X GET "https://api.skyvern.com/v1/runs/$RUN_ID" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY")
|
||||
|
||||
STATUS=$(echo "$RESPONSE" | jq -r '.status')
|
||||
|
||||
if [[ "$STATUS" == "completed" || "$STATUS" == "failed" || "$STATUS" == "terminated" || "$STATUS" == "timed_out" || "$STATUS" == "canceled" ]]; then
|
||||
echo "$RESPONSE" | jq '.output'
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
done
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
If using webhooks, the same `output` field appears in the webhook payload.
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Task Parameters"
|
||||
icon="sliders"
|
||||
href="/running-automations/task-parameters"
|
||||
>
|
||||
All available parameters for run_task
|
||||
</Card>
|
||||
<Card
|
||||
title="Run a Task"
|
||||
icon="play"
|
||||
href="/running-automations/run-a-task"
|
||||
>
|
||||
Execute tasks and retrieve results
|
||||
</Card>
|
||||
</CardGroup>
|
||||
490
docs/running-automations/run-a-task.mdx
Normal file
490
docs/running-automations/run-a-task.mdx
Normal file
@@ -0,0 +1,490 @@
|
||||
---
|
||||
title: Run a Task
|
||||
subtitle: Execute a single browser automation with natural language
|
||||
slug: running-automations/run-a-task
|
||||
---
|
||||
|
||||
A **Task** is the simplest way to automate a browser action.
|
||||
|
||||
You describe what you want in natural language, and Skyvern's AI navigates the web to complete it.
|
||||
|
||||
---
|
||||
|
||||
## Call `run_task`
|
||||
|
||||
A task has one required parameter and one commonly used optional parameter:
|
||||
|
||||
- **`prompt`** (required) — Natural language instructions describing what the AI should do
|
||||
- **`url`** (optional) — The starting page for the automation
|
||||
|
||||
For additional parameters like engines, proxies, and extraction schemas, see [Task Parameters](/running-automations/task-parameters).
|
||||
|
||||
When you call `run_task`, Skyvern spins up a cloud browser, navigates to the URL, and executes your prompt. A typical task takes 30–90 seconds depending on complexity.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
import asyncio
|
||||
from skyvern import Skyvern
|
||||
|
||||
async def main():
|
||||
client = Skyvern(api_key=os.getenv("SKYVERN_API_KEY"))
|
||||
|
||||
result = await client.run_task(
|
||||
prompt="Get the title of the top post",
|
||||
url="https://news.ycombinator.com",
|
||||
)
|
||||
|
||||
print(f"Run ID: {result.run_id}")
|
||||
print(f"Status: {result.status}")
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { SkyvernClient } from "@skyvern/client";
|
||||
|
||||
async function main() {
|
||||
const client = new SkyvernClient({
|
||||
apiKey: process.env.SKYVERN_API_KEY,
|
||||
});
|
||||
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the title of the top post",
|
||||
url: "https://news.ycombinator.com",
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Run ID: ${result.run_id}`);
|
||||
console.log(`Status: ${result.status}`);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the title of the top post",
|
||||
"url": "https://news.ycombinator.com"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Example response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "tsk_v2_486305187432193504",
|
||||
"status": "queued",
|
||||
"output": null,
|
||||
"downloaded_files": null,
|
||||
"recording_url": null,
|
||||
"screenshot_urls": null,
|
||||
"failure_reason": null,
|
||||
"created_at": "2026-01-20T11:52:29.276851",
|
||||
"modified_at": "2026-01-20T11:52:29.484284",
|
||||
"app_url": "https://app.skyvern.com/runs/wr_486305187432193510",
|
||||
"run_type": "task_v2"
|
||||
}
|
||||
```
|
||||
|
||||
The response includes a `run_id`. Use this ID to check status, fetch results, and retrieve artifacts.
|
||||
|
||||
<Warning>
|
||||
`run_task` returns immediately—the task is queued, not finished. Always poll or use webhooks to get results.
|
||||
</Warning>
|
||||
|
||||
---
|
||||
|
||||
## Get results
|
||||
|
||||
The `run_task` call queues the task and returns immediately.
|
||||
|
||||
Use the `run_id` to fetch results once the task reaches a terminal state.
|
||||
|
||||
| Status | Description |
|
||||
|--------|-------------|
|
||||
| `created` | Task initialized, not yet queued |
|
||||
| `queued` | Waiting for an available browser |
|
||||
| `running` | AI is navigating and executing |
|
||||
| `completed` | Task finished successfully—check `output` for results |
|
||||
| `failed` | Task encountered an error—check `failure_reason` and retry or adjust your prompt |
|
||||
| `terminated` | Task was manually stopped |
|
||||
| `timed_out` | Task exceeded time limit—increase `max_steps` or simplify the task |
|
||||
| `canceled` | Task was canceled before starting |
|
||||
|
||||
You have three options for retrieving results:
|
||||
|
||||
### Option 1: Polling
|
||||
|
||||
Poll `get_run` until status is terminal (`completed`, `failed`, `terminated`, `timed_out`, or `canceled`).
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
run_id = result.run_id
|
||||
|
||||
while True:
|
||||
run = await client.get_run(run_id)
|
||||
|
||||
if run.status in ["completed", "failed", "terminated", "timed_out", "canceled"]:
|
||||
break
|
||||
|
||||
await asyncio.sleep(5)
|
||||
|
||||
print(f"Output: {run.output}")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const runId = result.run_id;
|
||||
|
||||
while (true) {
|
||||
const run = await client.getRun(runId);
|
||||
|
||||
if (["completed", "failed", "terminated", "timed_out", "canceled"].includes(run.status)) {
|
||||
console.log(`Output: ${JSON.stringify(run.output)}`);
|
||||
break;
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
}
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
#!/bin/bash
|
||||
RUN_ID="YOUR_RUN_ID"
|
||||
|
||||
while true; do
|
||||
RESPONSE=$(curl -s -X GET "https://api.skyvern.com/v1/runs/$RUN_ID" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY")
|
||||
|
||||
STATUS=$(echo "$RESPONSE" | jq -r '.status')
|
||||
echo "Status: $STATUS"
|
||||
|
||||
if [[ "$STATUS" == "completed" || "$STATUS" == "failed" || "$STATUS" == "terminated" || "$STATUS" == "timed_out" || "$STATUS" == "canceled" ]]; then
|
||||
echo "$RESPONSE" | jq '.output'
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
done
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Warning>
|
||||
Your polling loop must check **all** terminal states: `completed`, `failed`, `terminated`, `timed_out`, `canceled`. Missing one causes infinite loops.
|
||||
</Warning>
|
||||
|
||||
### Option 2: Webhooks
|
||||
|
||||
Pass a `webhook_url` when creating the task. Skyvern sends a POST request to your URL when the task completes.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the title of the top post",
|
||||
url="https://news.ycombinator.com",
|
||||
webhook_url="https://your-server.com/webhook",
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the title of the top post",
|
||||
url: "https://news.ycombinator.com",
|
||||
webhook_url: "https://your-server.com/webhook",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the title of the top post",
|
||||
"url": "https://news.ycombinator.com",
|
||||
"webhook_url": "https://your-server.com/webhook"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Skyvern sends a POST request with the full run data when the task completes or fails.
|
||||
|
||||
### Option 3: Wait for completion (Python only)
|
||||
|
||||
Block until the task finishes instead of polling manually.
|
||||
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the title of the top post",
|
||||
url="https://news.ycombinator.com",
|
||||
wait_for_completion=True,
|
||||
)
|
||||
print(result.output)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Understand the response
|
||||
|
||||
The response from polling (`get_run`) and webhooks have slightly different structures. Both contain the core task data, but webhooks include additional metadata.
|
||||
|
||||
<CodeGroup>
|
||||
```json Polling Response
|
||||
{
|
||||
"run_id": "tsk_v2_486305187432193504",
|
||||
"status": "completed",
|
||||
"output": {
|
||||
"top_post_title": "Linux kernel framework for PCIe device emulation, in userspace"
|
||||
},
|
||||
"downloaded_files": [],
|
||||
"recording_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../recording.webm?...",
|
||||
"screenshot_urls": ["https://skyvern-artifacts.s3.amazonaws.com/.../screenshot_final.png?..."],
|
||||
"failure_reason": null,
|
||||
"errors": [],
|
||||
"step_count": 2,
|
||||
"run_type": "task_v2",
|
||||
"app_url": "https://app.skyvern.com/runs/wr_486305187432193510",
|
||||
"browser_session_id": null,
|
||||
"browser_profile_id": null,
|
||||
"created_at": "2026-01-20T11:52:29.276851",
|
||||
"modified_at": "2026-01-20T11:54:08.822807",
|
||||
"queued_at": "2026-01-20T11:52:29.483922",
|
||||
"started_at": "2026-01-20T11:52:31.835337",
|
||||
"finished_at": "2026-01-20T11:54:08.821985",
|
||||
"run_request": {
|
||||
"prompt": "Get the title of the top post",
|
||||
"url": "https://news.ycombinator.com/",
|
||||
"engine": "skyvern-2.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json Webhook Payload
|
||||
{
|
||||
"task_id": "tsk_v2_486306851394503256",
|
||||
"run_id": "tsk_v2_486306851394503256",
|
||||
"status": "completed",
|
||||
"output": {
|
||||
"top_post_title": "Linux kernel framework for PCIe device emulation, in userspace"
|
||||
},
|
||||
"summary": "I have successfully navigated to Hacker News and extracted the title of the top post.",
|
||||
"prompt": "Get the title of the top post",
|
||||
"url": "https://news.ycombinator.com/",
|
||||
"downloaded_files": [],
|
||||
"recording_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../recording.webm?...",
|
||||
"screenshot_urls": ["https://skyvern-artifacts.s3.amazonaws.com/.../screenshot_final.png?..."],
|
||||
"failure_reason": null,
|
||||
"errors": [],
|
||||
"step_count": 2,
|
||||
"run_type": "task_v2",
|
||||
"app_url": "https://app.skyvern.com/runs/wr_486306851394503262",
|
||||
"organization_id": "o_485917350850524254",
|
||||
"workflow_run_id": "wr_486306851394503262",
|
||||
"proxy_location": "RESIDENTIAL",
|
||||
"webhook_callback_url": "https://your-server.com/webhook",
|
||||
"created_at": "2026-01-20T11:58:57.414123",
|
||||
"modified_at": "2026-01-20T12:00:31.513449",
|
||||
"queued_at": "2026-01-20T11:58:57.607233",
|
||||
"started_at": "2026-01-20T11:58:59.395028",
|
||||
"finished_at": "2026-01-20T12:00:31.512692"
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
Webhook payloads differ from polling responses: webhooks include `summary` and `organization_id`; polling includes `run_request`. Plan your integration accordingly.
|
||||
</Note>
|
||||
|
||||
**Common fields (both polling and webhook):**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `run_id` | string | Unique identifier for this run |
|
||||
| `status` | string | Current status: `queued`, `running`, `completed`, `failed`, `terminated`, `timed_out`, `canceled` |
|
||||
| `output` | object \| null | Extracted data from the task |
|
||||
| `downloaded_files` | array | Files downloaded during execution |
|
||||
| `recording_url` | string \| null | Video recording of the browser session |
|
||||
| `screenshot_urls` | array \| null | Screenshots captured (latest first) |
|
||||
| `failure_reason` | string \| null | Error message if the run failed |
|
||||
| `errors` | array | List of errors encountered |
|
||||
| `step_count` | integer \| null | Number of steps executed |
|
||||
| `run_type` | string | Type of run: `task_v2`, `openai_cua`, `anthropic_cua` |
|
||||
| `app_url` | string | Link to view this run in Skyvern Cloud |
|
||||
| `created_at` | datetime | When the run was created |
|
||||
| `modified_at` | datetime | When the run was last updated |
|
||||
| `queued_at` | datetime \| null | When the run entered the queue |
|
||||
| `started_at` | datetime \| null | When execution began |
|
||||
| `finished_at` | datetime \| null | When execution completed |
|
||||
|
||||
**Polling-only fields:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `run_request` | object | Original request parameters (prompt, url, engine, etc.) |
|
||||
| `browser_session_id` | string \| null | ID of the browser session used |
|
||||
| `browser_profile_id` | string \| null | ID of the browser profile used |
|
||||
| `max_screenshot_scrolls` | integer \| null | Number of scrolls for screenshots |
|
||||
| `script_run` | object \| null | Script run result if AI fallback triggered |
|
||||
|
||||
**Webhook-only fields:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `task_id` | string | Same as `run_id` |
|
||||
| `summary` | string | AI-generated description of what was done |
|
||||
| `prompt` | string | The prompt from the original request |
|
||||
| `url` | string | The URL from the original request |
|
||||
| `organization_id` | string | Your organization ID |
|
||||
| `workflow_run_id` | string | Associated workflow run ID |
|
||||
| `proxy_location` | string | Proxy location used (e.g., `RESIDENTIAL`) |
|
||||
| `webhook_callback_url` | string | The webhook URL that received this payload |
|
||||
|
||||
---
|
||||
|
||||
## Get artifacts
|
||||
|
||||
The run response contains high-level data like `output`, `recording_url`, and `screenshot_urls`.
|
||||
|
||||
Every run also generates Artifacts, such as screenshots, reasoning logs, downloaded files, for observability. To get them, use `get_run_artifacts`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
artifacts = await client.get_run_artifacts(run_id)
|
||||
|
||||
for artifact in artifacts:
|
||||
print(f"{artifact.artifact_type}: {artifact.signed_url}")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
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"
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
This returns a list of artifacts.
|
||||
|
||||
**Example response:**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"artifact_id": "a_486305284826607484",
|
||||
"artifact_type": "recording",
|
||||
"uri": "s3://skyvern-artifacts/v1/production/.../recording.webm",
|
||||
"signed_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../recording.webm?...",
|
||||
"task_id": "tsk_486305246171901814",
|
||||
"step_id": "stp_486305250466869112",
|
||||
"workflow_run_id": "wr_486305187432193510",
|
||||
"workflow_run_block_id": null,
|
||||
"run_id": "tsk_v2_486305187432193504",
|
||||
"organization_id": "o_485917350850524254",
|
||||
"created_at": "2026-01-20T11:52:52.083001",
|
||||
"modified_at": "2026-01-20T11:52:52.083003"
|
||||
},
|
||||
{
|
||||
"artifact_id": "a_486305516754841578",
|
||||
"artifact_type": "screenshot_final",
|
||||
"uri": "s3://skyvern-artifacts/v1/production/.../screenshot_final.png",
|
||||
"signed_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../screenshot_final.png?...",
|
||||
"task_id": "tsk_486305439445430190",
|
||||
"step_id": "stp_486305439445430192",
|
||||
"workflow_run_id": "wr_486305187432193510",
|
||||
"workflow_run_block_id": null,
|
||||
"run_id": "tsk_v2_486305187432193504",
|
||||
"organization_id": "o_485917350850524254",
|
||||
"created_at": "2026-01-20T11:53:46.468908",
|
||||
"modified_at": "2026-01-20T11:53:46.468910"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Artifact fields:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `artifact_id` | string | Unique identifier for the artifact |
|
||||
| `artifact_type` | string | Type of artifact (see table below) |
|
||||
| `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 | Associated run ID (e.g., `tsk_v2_...`) |
|
||||
| `workflow_run_id` | string \| null | Associated workflow run ID |
|
||||
| `workflow_run_block_id` | string \| null | Associated workflow block ID |
|
||||
| `organization_id` | string | Organization that owns this artifact |
|
||||
| `created_at` | datetime | When the artifact was created |
|
||||
| `modified_at` | datetime | When the artifact was last modified |
|
||||
|
||||
**Artifact types:**
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `recording` | Full video of the browser session |
|
||||
| `screenshot` | Screenshot captured during execution |
|
||||
| `screenshot_action` | Screenshot taken after an action |
|
||||
| `screenshot_final` | Final screenshot when task completed |
|
||||
| `screenshot_llm` | Screenshot sent to the LLM for analysis |
|
||||
| `html` | Page HTML at various points |
|
||||
| `html_scrape` | Scraped HTML content |
|
||||
| `html_action` | HTML captured after an action |
|
||||
| `har` | HTTP Archive file for network debugging |
|
||||
| `trace` | Execution trace data |
|
||||
| `pdf` | PDF files generated or downloaded |
|
||||
| `script_file` | Generated script files |
|
||||
| `browser_console_log` | Browser console output |
|
||||
| `skyvern_log` | Skyvern execution logs |
|
||||
| `skyvern_log_raw` | Raw Skyvern execution logs |
|
||||
| `llm_prompt` | Prompt sent to the LLM |
|
||||
| `llm_request` | Full request sent to the LLM |
|
||||
| `llm_response` | Response from the LLM |
|
||||
| `llm_response_parsed` | Parsed LLM response |
|
||||
| `llm_response_rendered` | Rendered LLM response |
|
||||
| `visible_elements_tree` | DOM tree of visible elements |
|
||||
| `visible_elements_tree_trimmed` | Trimmed DOM tree |
|
||||
| `visible_elements_tree_in_prompt` | DOM tree included in prompt |
|
||||
| `visible_elements_id_css_map` | CSS selector map for elements |
|
||||
| `visible_elements_id_frame_map` | Frame map for elements |
|
||||
| `visible_elements_id_xpath_map` | XPath map for elements |
|
||||
| `hashed_href_map` | Hashed href mapping |
|
||||
|
||||
You can filter by artifact type using query parameters:
|
||||
|
||||
```bash
|
||||
curl -X GET "https://api.skyvern.com/v1/runs/RUN_ID/artifacts?artifact_type=screenshot&artifact_type=recording" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Task Parameters"
|
||||
icon="sliders"
|
||||
href="/running-automations/task-parameters"
|
||||
>
|
||||
Configure engines, proxies, extraction schemas, etc when running a task
|
||||
</Card>
|
||||
<Card
|
||||
title="Extract Structured Data"
|
||||
icon="database"
|
||||
href="/running-automations/extract-structured-data"
|
||||
>
|
||||
Define a schema to get typed JSON output from your automations
|
||||
</Card>
|
||||
</CardGroup>
|
||||
842
docs/running-automations/task-parameters.mdx
Normal file
842
docs/running-automations/task-parameters.mdx
Normal file
@@ -0,0 +1,842 @@
|
||||
---
|
||||
title: Task Parameters
|
||||
subtitle: Configure how your task runs
|
||||
slug: running-automations/task-parameters
|
||||
---
|
||||
|
||||
This page covers all parameters you can pass to `run_task`.
|
||||
|
||||
Only `prompt` is a required parameter.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Quick reference
|
||||
|
||||
| Parameter | Type | Use this to |
|
||||
|-----------|------|-------------|
|
||||
| [`prompt`](#prompt) **(Required)** | string | Give natural language instructions for the AI |
|
||||
| [`url`](#url) | string | Give a starting URL for the task |
|
||||
| [`engine`](#engine) | string | Choose a different Agent model |
|
||||
| [`data_extraction_schema`](#data_extraction_schema) | object | Get consistent, structured JSON output |
|
||||
| [`max_steps`](#max_steps) | integer | Limit how long the Agent runs and cap costs |
|
||||
| [`proxy_location`](#proxy_location) | string \| object | Access geo-restricted content or reduce bot detection |
|
||||
| [`browser_session_id`](#browser_session_id) | string | Maintain state (cookies, login) across multiple tasks |
|
||||
| [`totp_identifier`](#totp_identifier) | string | Handle 2FA when pushing codes to Skyvern |
|
||||
| [`totp_url`](#totp_url) | string | Have Skyvern fetch 2FA codes from your endpoint |
|
||||
| [`error_code_mapping`](#error_code_mapping) | object | Get custom error codes for programmatic handling |
|
||||
| [`webhook_url`](#webhook_url) | string | Get notified when the task completes |
|
||||
| [`title`](#title) | string | Label the task in the Skyvern UI |
|
||||
| [`extra_http_headers`](#extra_http_headers) | object | Add custom headers (e.g., Authorization) to browser requests |
|
||||
| [`publish_workflow`](#publish_workflow) | boolean | Convert this task into a reusable workflow |
|
||||
| [`max_screenshot_scrolls`](#max_screenshot_scrolls) | integer | Capture lazy-loaded content in screenshots |
|
||||
| [`browser_address`](#browser_address) | string | Connect to your own browser for local development |
|
||||
| [`include_action_history_in_verification`](#include_action_history_in_verification) | boolean | Improve verification accuracy for multi-step forms |
|
||||
| [`model`](#model) | object | Configure model settings (e.g., temperature) |
|
||||
|
||||
---
|
||||
|
||||
## `prompt`
|
||||
|
||||
**Required.** Natural language instructions describing what the AI should do.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Find the cheapest flight from NYC to LAX on March 15"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Find the cheapest flight from NYC to LAX on March 15",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Find the cheapest flight from NYC to LAX on March 15"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Be specific about your goal and what data you want extracted. The more detailed your prompt, the better the results.
|
||||
|
||||
---
|
||||
|
||||
## `url`
|
||||
|
||||
The starting page for the automation. Skyvern navigates from here based on your prompt.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the top headline",
|
||||
url="https://news.ycombinator.com"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the top headline",
|
||||
url: "https://news.ycombinator.com",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the top headline",
|
||||
"url": "https://news.ycombinator.com"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
If not provided, Skyvern attempts to determine an appropriate starting URL from your prompt.
|
||||
|
||||
---
|
||||
|
||||
## `engine`
|
||||
|
||||
The AI engine that powers the task. These are not iterations—they're suited for different purposes.
|
||||
|
||||
| Engine | Description |
|
||||
|--------|-------------|
|
||||
| `skyvern-2.0` | **Default.** Multi-objective, flexible, handles complex multi-step tasks. 85.85% on WebVoyager benchmark. Slower and more expensive. |
|
||||
| `skyvern-1.0` | Single objective, precise, faster, cheaper. Best for simple tasks like form filling or single-page extraction. |
|
||||
| `openai-cua` | OpenAI's Computer Use Agent |
|
||||
| `anthropic-cua` | Anthropic Claude Sonnet with computer use |
|
||||
| `ui-tars` | UI-TARS model (Seed1.5-VL) via Doubao API |
|
||||
|
||||
<Tip>
|
||||
Use `skyvern-1.0` when you have a clear, single goal and want faster, cheaper execution. Use `skyvern-2.0` when the task requires flexibility or multiple steps.
|
||||
</Tip>
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Fill out the contact form",
|
||||
engine="skyvern-1.0"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Fill out the contact form",
|
||||
engine: "skyvern-1.0",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Fill out the contact form",
|
||||
"engine": "skyvern-1.0"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `data_extraction_schema`
|
||||
|
||||
A [JSON Schema](https://json-schema.org/) defining the structure of output data.
|
||||
|
||||
Use this when you need consistent, typed responses.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Find the top post on Hacker News",
|
||||
data_extraction_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The title of the top post"
|
||||
},
|
||||
"points": {
|
||||
"type": "integer",
|
||||
"description": "Number of points"
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Find the top post on Hacker News",
|
||||
data_extraction_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: {
|
||||
type: "string",
|
||||
description: "The title of the top post",
|
||||
},
|
||||
points: {
|
||||
type: "integer",
|
||||
description: "Number of points",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Find the top post on Hacker News",
|
||||
"data_extraction_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The title of the top post"
|
||||
},
|
||||
"points": {
|
||||
"type": "integer",
|
||||
"description": "Number of points"
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Without a schema, output format varies based on what the AI extracts. With a schema, output matches your defined structure.
|
||||
|
||||
---
|
||||
|
||||
## `max_steps`
|
||||
|
||||
Maximum number of steps the task can take. The task fails if it exceeds this limit.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the current stock price of AAPL",
|
||||
max_steps=10
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the current stock price of AAPL",
|
||||
max_steps: 10,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the current stock price of AAPL",
|
||||
"max_steps": 10
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
On the cloud-hosted version, you're billed per step. Set this to a reasonable value during development to cap costs.
|
||||
|
||||
<Warning>
|
||||
Set `max_steps` during development to avoid runaway costs. A task that loops or gets stuck will keep consuming steps until it hits this limit.
|
||||
</Warning>
|
||||
|
||||
---
|
||||
|
||||
## `proxy_location`
|
||||
|
||||
Route browser traffic through a residential proxy in a specific location.
|
||||
|
||||
Use this for geo-restricted content or to reduce bot detection.
|
||||
|
||||
**Country-level pools:**
|
||||
|
||||
| Value | Location |
|
||||
|-------|----------|
|
||||
| `RESIDENTIAL` | Random US residential (default) |
|
||||
| `RESIDENTIAL_GB` | United Kingdom |
|
||||
| `RESIDENTIAL_DE` | Germany |
|
||||
| `RESIDENTIAL_FR` | France |
|
||||
| `RESIDENTIAL_ES` | Spain |
|
||||
| `RESIDENTIAL_IE` | Ireland |
|
||||
| `RESIDENTIAL_IN` | India |
|
||||
| `RESIDENTIAL_JP` | Japan |
|
||||
| `RESIDENTIAL_AU` | Australia |
|
||||
| `RESIDENTIAL_CA` | Canada |
|
||||
| `RESIDENTIAL_BR` | Brazil |
|
||||
| `RESIDENTIAL_MX` | Mexico |
|
||||
| `RESIDENTIAL_AR` | Argentina |
|
||||
| `RESIDENTIAL_NZ` | New Zealand |
|
||||
| `RESIDENTIAL_ZA` | South Africa |
|
||||
| `RESIDENTIAL_IT` | Italy |
|
||||
| `RESIDENTIAL_NL` | Netherlands |
|
||||
| `RESIDENTIAL_PH` | Philippines |
|
||||
| `RESIDENTIAL_TR` | Turkey |
|
||||
| `RESIDENTIAL_ISP` | ISP proxy |
|
||||
| `NONE` | No proxy |
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get UK-specific pricing",
|
||||
proxy_location="RESIDENTIAL_GB"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get UK-specific pricing",
|
||||
proxy_location: "RESIDENTIAL_GB",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get UK-specific pricing",
|
||||
"proxy_location": "RESIDENTIAL_GB"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Granular targeting (US states/cities):**
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get California pricing",
|
||||
proxy_location={
|
||||
"country": "US",
|
||||
"subdivision": "CA",
|
||||
"city": "San Francisco"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get California pricing",
|
||||
proxy_location: {
|
||||
country: "US",
|
||||
subdivision: "CA",
|
||||
city: "San Francisco",
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get California pricing",
|
||||
"proxy_location": {
|
||||
"country": "US",
|
||||
"subdivision": "CA",
|
||||
"city": "San Francisco"
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The full list of available proxy locations is shown above. Use `NONE` to disable proxies.
|
||||
|
||||
<Warning>
|
||||
For geo-restricted sites, `proxy_location` is required—without it, you'll get blocked or see wrong regional content (e.g., US prices instead of UK prices).
|
||||
</Warning>
|
||||
|
||||
---
|
||||
|
||||
## `browser_session_id`
|
||||
|
||||
Run the task in an existing persistent browser session.
|
||||
|
||||
Use this to maintain state (cookies, localStorage) across multiple tasks.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Extract account data",
|
||||
browser_session_id="pbs_123"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Extract account data",
|
||||
browser_session_id: "pbs_123",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Extract account data",
|
||||
"browser_session_id": "pbs_123"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Browser sessions persist cookies, localStorage, and authentication state across multiple tasks.
|
||||
|
||||
---
|
||||
|
||||
## `totp_identifier`
|
||||
|
||||
Identifier for TOTP codes when you push codes to Skyvern's API.
|
||||
|
||||
Use this for two-factor authentication during task execution.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Log in and extract account balance",
|
||||
totp_identifier="my-2fa-credential"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Log in and extract account balance",
|
||||
totp_identifier: "my-2fa-credential",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Log in and extract account balance",
|
||||
"totp_identifier": "my-2fa-credential"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
TOTP codes are used for two-factor authentication during automated logins.
|
||||
|
||||
---
|
||||
|
||||
## `totp_url`
|
||||
|
||||
URL that Skyvern calls to fetch TOTP codes when needed.
|
||||
|
||||
Use this when Skyvern should retrieve codes from your endpoint.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Log in and extract account balance",
|
||||
totp_url="https://your-server.com/totp"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Log in and extract account balance",
|
||||
totp_url: "https://your-server.com/totp",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Log in and extract account balance",
|
||||
"totp_url": "https://your-server.com/totp"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
TOTP codes are used for two-factor authentication during automated logins.
|
||||
|
||||
---
|
||||
|
||||
## `error_code_mapping`
|
||||
|
||||
Map specific error conditions to custom error codes.
|
||||
|
||||
Use this to make programmatic error handling easier.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Log in and extract data",
|
||||
error_code_mapping={
|
||||
"login_failed": "The login credentials are incorrect or the account is locked",
|
||||
"maintenance_mode": "The website is down for maintenance"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Log in and extract data",
|
||||
error_code_mapping: {
|
||||
login_failed: "The login credentials are incorrect or the account is locked",
|
||||
maintenance_mode: "The website is down for maintenance",
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Log in and extract data",
|
||||
"error_code_mapping": {
|
||||
"login_failed": "The login credentials are incorrect or the account is locked",
|
||||
"maintenance_mode": "The website is down for maintenance"
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
If Skyvern encounters a login failure matching your description, `output` contains `{"error": "login_failed"}` instead of a generic error message.
|
||||
|
||||
---
|
||||
|
||||
## `webhook_url`
|
||||
|
||||
URL to receive a POST request when the task completes.
|
||||
|
||||
Use this instead of polling for production systems.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Extract pricing data",
|
||||
webhook_url="https://your-server.com/webhook"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Extract pricing data",
|
||||
webhook_url: "https://your-server.com/webhook",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Extract pricing data",
|
||||
"webhook_url": "https://your-server.com/webhook"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Skyvern sends a POST request with the full run data when the task completes or fails.
|
||||
|
||||
---
|
||||
|
||||
## `title`
|
||||
|
||||
Display name for the task in the Skyvern UI.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Get the top post",
|
||||
title="HN Top Post Scraper"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Get the top post",
|
||||
title: "HN Top Post Scraper",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Get the top post",
|
||||
"title": "HN Top Post Scraper"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `extra_http_headers`
|
||||
|
||||
Additional HTTP headers to include in browser requests.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Access protected resource",
|
||||
extra_http_headers={
|
||||
"Authorization": "Bearer your-token"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Access protected resource",
|
||||
extra_http_headers: {
|
||||
Authorization: "Bearer your-token",
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Access protected resource",
|
||||
"extra_http_headers": {
|
||||
"Authorization": "Bearer your-token"
|
||||
}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `publish_workflow`
|
||||
|
||||
Convert this task into a reusable workflow. Only available for `skyvern-2.0`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Fill out the contact form with provided data",
|
||||
publish_workflow=True
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Fill out the contact form with provided data",
|
||||
publish_workflow: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Fill out the contact form with provided data",
|
||||
"publish_workflow": true
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `max_screenshot_scrolls`
|
||||
|
||||
Number of scrolls for post-action screenshots.
|
||||
|
||||
Use this for pages with lazy-loaded content.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Extract all product listings",
|
||||
max_screenshot_scrolls=3
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Extract all product listings",
|
||||
max_screenshot_scrolls: 3,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Extract all product listings",
|
||||
"max_screenshot_scrolls": 3
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `browser_address`
|
||||
|
||||
Connect to a browser at a specific CDP address.
|
||||
|
||||
Use this for local development only.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Automate my local browser",
|
||||
browser_address="http://127.0.0.1:9222"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Automate my local browser",
|
||||
browser_address: "http://127.0.0.1:9222",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Automate my local browser",
|
||||
"browser_address": "http://127.0.0.1:9222"
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `model`
|
||||
|
||||
Optional model configuration for the task.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Extract data from the page",
|
||||
model={"temperature": 0.5}
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Extract data from the page",
|
||||
model: { temperature: 0.5 },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Extract data from the page",
|
||||
"model": {"temperature": 0.5}
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## `include_action_history_in_verification`
|
||||
|
||||
Include action history when verifying task completion. Default: `false`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = await client.run_task(
|
||||
prompt="Complete the multi-step form",
|
||||
include_action_history_in_verification=True
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.runTask({
|
||||
body: {
|
||||
prompt: "Complete the multi-step form",
|
||||
include_action_history_in_verification: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
|
||||
-H "x-api-key: $SKYVERN_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "Complete the multi-step form",
|
||||
"include_action_history_in_verification": true
|
||||
}'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Extract Structured Data"
|
||||
icon="database"
|
||||
href="/running-automations/extract-structured-data"
|
||||
>
|
||||
Define a schema to get typed JSON output
|
||||
</Card>
|
||||
<Card
|
||||
title="Run a Task"
|
||||
icon="play"
|
||||
href="/running-automations/run-a-task"
|
||||
>
|
||||
Execute tasks and retrieve results
|
||||
</Card>
|
||||
</CardGroup>
|
||||
Reference in New Issue
Block a user