Webskillet
Get started

Introduction

Webskillet runs web tasks described in plain English — scraping, form-filling, multi-step automation — and hands back a structured result.

Webskillet runs web tasks described in natural language. You describe what you want done — scrape a directory, fill out a multi-page form, pull rows out of a table — and Webskillet's browser agent figures out how, writing and running code as needed, and hands back a structured result. No selectors, no scraping scripts to maintain.

How it works

  1. Describe the task — a plain-English instruction, plus an optional starting URL, input parameters, and an output schema
  2. Webskillet runs it — a browser agent navigates the page and generates code where it helps, reusing a skillet (saved code, knowledge, and notes) if you point it at one
  3. Get the result — poll the run until it's completed; small results come back inline, large ones as a download link

Each run is asynchronous: POST /api/v1/runs/start returns a run ID immediately, and you poll GET /api/v1/runs/:id until it finishes.

When to use Webskillet

Use Webskillet when:

  • The task benefits from generated code — crawling, multi-entity extraction, or repeated multi-step actions
  • You're running the same or a similar task repeatedly and want it to get faster and cheaper over time
  • You'd rather describe the task than write and maintain the automation yourself

Core concepts

Task

The task field is a natural-language instruction describing what to do — it's the only required field on a run. Everything else narrows or guides that instruction.

Output schema

The outputSchema field is a JSON Schema (draft 2020-12) describing the shape of data you want back. Webskillet uses it to guide extraction and validate the result. Omit it and the agent infers a shape from the task and the page.

Skillets

A skillet is the saved automation behind a run — the generated code, what the agent learned about the site, and its run notes — stored under an id. Pass a skilletId to reuse one: Webskillet loads the saved code and runs it directly, which is faster and cheaper than starting from scratch. If the run succeeds, the skillet is updated with anything new it learned; if it fails, Webskillet repairs the code and only saves the fix back once a run succeeds. Failed runs never leave a skillet worse than it started.

Omit skilletId and Webskillet creates a new skillet for you, returning its id in the result (skillet.id) so you can reuse it next time. The same skillet works across different URLs and parameters as long as the underlying task is the same shape — use separate skillets for genuinely different automations.

Runs

A run is a single execution of a task. Runs are asynchronous — start one with POST /api/v1/runs/start and poll GET /api/v1/runs/:id until status is completed or canceled. Inline outputs are returned directly under result; larger outputs return a file descriptor. GET /api/v1/runs lists your recent runs.

API key

All requests require an API key in the x-api-key header. Grab yours from the sidebar in the Webskillet app.

Example

The simplest call: provide a task, URL, and schema, then poll for the result.

const startRes = await fetch("https://webskillet.ai/api/v1/runs/start", {
  method: "POST",
  headers: {
    "x-api-key": process.env.WEBSKILLET_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    task: "Extract the title, points, and URL for the top stories",
    startUrl: "https://news.ycombinator.com",
    outputSchema: {
      type: "array",
      items: {
        type: "object",
        properties: {
          title: { type: "string" },
          points: { type: "number" },
          url: { type: "string" },
        },
      },
    },
  }),
});

const { id } = await startRes.json();

// Poll until done
let run;
while (true) {
  const res = await fetch(`https://webskillet.ai/api/v1/runs/${id}`, {
    headers: { "x-api-key": process.env.WEBSKILLET_API_KEY },
  });
  run = await res.json();
  if (run.status === "completed" || run.status === "canceled") break;
  await new Promise((r) => setTimeout(r, 2000));
}

console.log(run.result, run.skillet);

Example response

{
  "id": "ru_7Km2pQr9Vx4Nz8Lc1Hd6B",
  "status": "completed",
  "outcome": "success",
  "result": [
    {
      "title": "Show HN: I built a thing",
      "points": 312,
      "url": "https://example.com"
    },
    { "title": "Ask HN: Best practices for X", "points": 204, "url": null }
  ],
  "skillet": {
    "id": "skl_abc123",
    "used": false,
    "created": true,
    "updated": true
  }
}

FAQ

Next steps

On this page