# AI Web Scraper – JSON Schema Data Extractor (`brisaworks/schema-json-extractor`) Actor

AI web scraper: give URLs and your own JSON Schema or a ready-made preset (product, job, event, article); get one schema-valid JSON object per page. Claude reads page text and JSON-LD, every answer is validated and retried with the errors, and invalid output is free. Uses your own Anthropic API key.

- **URL**: https://apify.com/brisaworks/schema-json-extractor.md
- **Developed by:** [Brisa Works](https://apify.com/brisaworks) (community)
- **Categories:** AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 page extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

An **AI web scraper** that turns any page into structured data: give a list of URLs and pick a ready-made schema (product, job, event, article) or paste your own **JSON Schema**; get back one JSON object per page that **validates against that schema**. Claude reads each page (text plus any JSON-LD) and fills your fields; every result is checked with a JSON Schema validator, invalid answers are sent back to the model with the errors, and anything still invalid is returned free. Runs on your own Anthropic API key, so you pay Anthropic's token prices directly.

![Dataset table with four extracted rows: a product, a job posting, an event and an article, each with status ok, valid true, its preset and the JSON data](https://api.apify.com/v2/key-value-stores/rabUnlqsZdMugucmh/records/schema-json-extractor--output-table.png)

**Contents:** [What it does](#what-it-does) · [How to use](#how-to-use) · [Presets](#presets-ready-made-schemas) · [Use cases](#use-cases-with-ready-inputs) · [Writing a schema](#how-to-write-a-good-json-schema) · [Input](#input) · [Output](#output) · [Pricing](#pricing) · [Comparison](#how-it-compares) · [MCP](#use-with-ai-agents-mcp) · [API](#api) · [Scheduling](#scheduling-and-integrations) · [FAQ](#faq) · [Limits](#limits)

### What it does

- Fetches each page once (no crawling), honours robots.txt, and converts it to clean text, keeping JSON-LD structured data.
- Uses the schema you choose: one of four presets, or your own JSON Schema, which always wins when both are set.
- Sends the page and the schema to Claude using structured outputs, adapting the schema where the API needs it (closed objects, constraints moved into descriptions); falls back to plain JSON prompting for schemas the API cannot take.
- Validates every answer against your original schema (draft-07 / 2020-12, formats included) and retries with the validation errors.
- Charges only for pages whose JSON validates. Previews, blocked pages, failed fetches and answers that still fail validation are free.

![How it works: your input, fetch once, Claude fills the schema, validate; valid rows are charged $0.01, invalid, blocked or keyless rows are free](https://api.apify.com/v2/key-value-stores/rabUnlqsZdMugucmh/records/schema-json-extractor--how-it-works.png)

### How to use

1. Add start URLs: the exact pages you want read.
2. Pick a **Preset schema** (product, job, event or article), or paste your own **JSON Schema**. Leave the JSON Schema field empty to use the preset.
3. Add your Anthropic API key (console.anthropic.com). Without a key the run returns free page previews, so you can check that the pages load before you spend anything.
4. Optionally pick a model (`claude-haiku-5-5` by default; `claude-sonnet-5-5` for hard pages) and add extra instructions, such as "prices in EUR".
5. Run, then export the dataset as JSON, CSV or Excel, or call the Actor from your own code or AI agent through the Apify API.

The form opens with a working example: the product preset on a page of [Books to Scrape](https://books.toscrape.com/), a demo shop made for scraping practice. Run it without a key to see the free preview; add your key to get the product record shown above.

### Presets (ready-made schemas)

In each preset every field is required and may be `null`: Claude answers every field and says `null` when the page does not state it. Dates are `YYYY-MM-DD`, checked as dates.

| Preset | Fields in `data` |
|---|---|
| `product` | `name`, `brand`, `sku`, `price` (number), `currency` (ISO code), `availability`, `inStock`, `rating`, `reviewCount`, `category`, `description`, `imageUrl` |
| `job` | `title`, `company`, `location`, `remote`, `employmentType`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `datePosted`, `applyUrl`, `skills` (list), `summary` |
| `event` | `name`, `startDate`, `endDate`, `startTime`, `venue`, `city`, `country`, `online`, `organizer`, `price`, `eventUrl`, `summary` |
| `article` | `headline`, `authors` (list), `datePublished`, `dateModified`, `publisher`, `language`, `summary`, `keyPoints` (list), `tags` (list) |

Need other fields? Paste your own schema in **JSON Schema**: it replaces the preset, and the log says so.

### Use cases with ready inputs

Each input below runs as it is; add `"anthropicApiKey"` to get data instead of previews.

**1. Product data for price monitoring or a catalogue import.** Name, SKU, price as a number and stock from any shop's product pages.

```json
{
  "startUrls": [{ "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html" }],
  "preset": "product"
}
```

**2. Job postings** for a job board or a hiring dashboard: `{"startUrls": [{"url": "https://realpython.github.io/fake-jobs/jobs/senior-python-developer-0.html"}], "preset": "job"}`

**3. Event listings** for a calendar or a newsletter: `{"startUrls": [{"url": "https://www.python.org/events/python-events/2209/"}], "preset": "event"}`

**4. Article metadata and summaries** for a reading list or a RAG pipeline: `{"startUrls": [{"url": "https://crawlee.dev/blog/crawlee-for-python-v1"}], "preset": "article"}`

**5. Every item of a list page, with your own schema.** One record per page holds an array of all the items on it.

```json
{
  "startUrls": [{ "url": "https://books.toscrape.com/catalogue/category/books/poetry_23/index.html" }],
  "jsonSchema": {
    "type": "object",
    "properties": {
      "books": { "type": "array", "items": { "type": "object",
        "properties": { "title": { "type": "string" }, "price": { "type": "number" }, "inStock": { "type": "boolean" } },
        "required": ["title", "price", "inStock"] } }
    },
    "required": ["books"]
  }
}
```

#### Example tasks

Ready-made tasks with these inputs, to open and run in one click:

- [Extract product name, price, SKU and stock to JSON](https://apify.com/brisaworks/schema-json-extractor/examples/ai-extract-product-price-sku-stock-json)
- [Scrape job postings into JSON: title, company, salary, location](https://apify.com/brisaworks/schema-json-extractor/examples/ai-extract-job-postings-salary-json)
- [Extract event name, dates, venue and city from event pages](https://apify.com/brisaworks/schema-json-extractor/examples/ai-extract-event-dates-venue-json)
- [Extract article headline, author, date and summary](https://apify.com/brisaworks/schema-json-extractor/examples/ai-extract-article-author-date-summary)
- [Scrape a list page into a JSON array with your own schema](https://apify.com/brisaworks/schema-json-extractor/examples/ai-extract-list-page-custom-json-schema)

### How to write a good JSON Schema

The schema is both the instruction to Claude and the contract your data must meet. A few rules give much better results:

- **Describe every field.** `"description": "Price as a number, without currency symbol"` does more than the field name alone. Say the unit, the format and what to do with ranges.
- **Use real types.** `number` for prices and counts, `boolean` for yes/no, `integer` for counts. The validator rejects `"£53.74"` for a `number`, and the retry asks Claude to fix it.
- **Allow `null` for anything a page may not state:** `"type": ["string", "null"]`. Without it, Claude must put something in a required field and may guess; with it, a missing value comes back as `null`.
- **Make fields required,** so your columns stay the same on every row.
- **Use formats for dates, emails and links:** `"format": "date"`, `"email"`, `"uri"`. They are checked on every answer. Use `uri` only when pages give full links; a relative link fails the check.
- **Use `enum` for fixed choices** (`["full-time", "part-time"]`) so values match across sites.
- **For list pages, wrap the items in an array** (use case 5): one record and one charge per page.
- **Keep it flat and small.** Claude's structured outputs allow at most 16 fields with a union type (such as `["string", "null"]`) and 24 optional fields per schema. Each preset stays inside these limits.

**Good:** `"price": { "type": ["number", "null"], "description": "Current price as a number, without currency symbol; null if not shown" }`
**Weak:** `"price": { "type": "string" }`: you get `"£53.74"`, `"53,74 €"` or `"From $10"` from different sites.

### Input

| Field | Description |
|---|---|
| `startUrls` | Pages to extract (required). |
| `preset` | `product`, `job`, `event` or `article`: a ready-made schema, used when `jsonSchema` is empty. |
| `jsonSchema` | Your own JSON Schema. Wins over `preset`. |
| `anthropicApiKey` | Your Anthropic key (secret). |
| `model` | Default `claude-haiku-5-5`. |
| `instructions` | Extra guidance for the model. |
| `maxPageChars` | Page text sent per page (default 60,000 characters). |
| `maxRetriesOnInvalid` | Corrective retries (default 1). |
| `respectRobotsTxt`, `includePageText` | Crawling courtesy; return the page text too. |

A run needs a preset or a schema: with neither, it stops at once with a message and costs nothing.

```json
{
  "startUrls": [{ "url": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html" }],
  "preset": "product",
  "instructions": "Description: one sentence only",
  "model": "claude-haiku-5-5",
  "anthropicApiKey": "••••••"
}
```

### Output

One row per page. With the default input and a key, the product preset gives (`data` values as stated on the page):

```json
{
  "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html",
  "status": "ok",
  "valid": true,
  "data": {
    "name": "Tipping the Velvet",
    "brand": null,
    "sku": "90fa61229261140a",
    "price": 53.74,
    "currency": "GBP",
    "availability": "In stock (20 available)",
    "inStock": true,
    "rating": null,
    "reviewCount": 0,
    "category": "Historical Fiction",
    "description": "Nan King, an oyster girl, is captivated by the music hall star Kitty Butler...",
    "imageUrl": "https://books.toscrape.com/media/cache/08/e9/08e94f3731d7d6b760dfbfbc02ca5c62.jpg"
  },
  "validationErrors": [],
  "preset": "product",
  "title": "Tipping the Velvet | Books to Scrape - Sandbox",
  "model": "claude-haiku-5-5",
  "structuredOutput": true,
  "inputTokens": 1200,
  "outputTokens": 150,
  "truncated": false
}
```

Token counts vary by page. Without a key, the same input gives this free preview (from a real run on 2026-10-22):

```json
{
  "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html",
  "status": "no_api_key",
  "preset": "product",
  "title": "Tipping the Velvet | Books to Scrape - Sandbox",
  "textLength": 1574,
  "textPreview": "Books to Scrape We love being scraped!\nHome\nBooks\nHistorical Fiction\nTipping the Velvet\nTipping the Velvet\n£53.74\nIn stock (20 available)…",
  "error": "Add your Anthropic API key to extract JSON. This preview is free."
}
```

`status` is `ok` (charged) or one of the free statuses: `invalid_output` (with `validationErrors`), `no_api_key` (page preview), `blocked_by_robots`, `robots_unreachable`, `fetch_failed` or `error`. `preset` is the preset used, or `null` for your own schema.

### Pricing

| Event | Price | Per 1,000 | Charged when |
|---|---|---|---|
| `page-extracted` | $0.01 | $10.00 | A page yields JSON that validates against your schema |

Apify subscription discounts: Bronze $0.009 ($9 per 1,000), Silver $0.008 ($8 per 1,000), Gold $0.007 ($7 per 1,000). Claude tokens are billed by Anthropic to your account.

#### How much does AI web scraping cost?

- 1,000 pages with valid JSON: $10.00 here, plus Claude tokens on your Anthropic account. With `claude-haiku-5-5` ($0.10 per million input tokens and $0.50 per million output tokens, Anthropic's price list on 2026-10-22), a typical 10,000-token page costs about $0.001, so about $1 of tokens for 1,000 pages: about $11 in all.
- Pages whose answer still fails your schema after the retries cost nothing here (Claude tokens are still used).
- Keyless previews, robots.txt blocks and failed fetches cost nothing and use no tokens.
- Apify adds its standard small run-start fee.

Set a maximum cost per run in the run options: the Actor checks it before sending each page to Claude, so it does not spend your tokens on pages it could not deliver, and stops before going over it.

#### Cost against Apify's AI Web Scraper

Apify's own [AI Web Scraper](https://apify.com/apify/ai-web-scraper) costs $30 for 1,000 pages on the Free plan (Store price on 2026-10-22), AI tokens included. Here, 1,000 valid pages cost $10 plus about $1 of Haiku tokens on your Anthropic account. For 10,000 product pages a month that is about $110 against $300. You need your own Anthropic key, and pages that need a browser are out of reach (see [Limits](#limits)).

### How it compares

Facts from each Actor's own README and input form, and Store prices, read on 2026-10-22.

| | This Actor | [Apify AI Web Scraper](https://apify.com/apify/ai-web-scraper) | [tidytools AI Web Data Extractor](https://apify.com/tidytools/ai-web-data-extractor) | [eloquent_mountain AI Web Scraper](https://apify.com/eloquent_mountain/ai-web-scraper-extract-data-with-ease) |
|---|---|---|---|---|
| Price for 1,000 (Free plan) | $10 per page + your Claude tokens | $30 per page, tokens included | $10 per page, tokens included | $10 per vision call, tokens included |
| Describe the output with | presets or a full JSON Schema | a prompt | fields, a prompt or a JSON Schema; presets | a prompt; optional typed output fields |
| Every answer validated against the schema, with a retry | yes | no schema input | typed values and a completeness score | not stated |
| Pages that fail are free | yes, also answers that fail validation | not stated | yes | not stated |
| Choice of model | any Claude model | no model field | not stated | Gemini models |
| Browser for JavaScript pages | no | yes | yes (fallback) | yes |
| Proxy | no | yes | through Apify's network or your proxy | yes |
| Follows links or sitemaps | no | yes (scout and agentic modes) | follows links from a list page | yes |
| Your own LLM key needed | yes | no | no | no |

Pick this one when the data must match a schema every time or you want to choose the Claude model; pick another for JavaScript-heavy sites, crawling, or runs without an LLM key.

### Use with AI agents (MCP)

Connect any MCP client (Claude Desktop, Claude Code, Cursor) to Apify's hosted MCP server at https://mcp.apify.com with this Actor as the tool `brisaworks--schema-json-extractor` (`https://mcp.apify.com?tools=brisaworks/schema-json-extractor`).

Example prompt: *"Use brisaworks--schema-json-extractor with the job preset on these three job links and make me a table of company, salary range and location."* The agent calls the tool with:

```json
{
  "startUrls": [
    { "url": "https://realpython.github.io/fake-jobs/jobs/senior-python-developer-0.html" },
    { "url": "https://realpython.github.io/fake-jobs/jobs/energy-engineer-1.html" }
  ],
  "preset": "job",
  "anthropicApiKey": "sk-ant-..."
}
```

### API

Run the Actor and get its dataset with your Apify token. cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/brisaworks~schema-json-extractor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html"}],"preset":"product","anthropicApiKey":"'"$ANTHROPIC_API_KEY"'"}'
```

Node.js (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('brisaworks/schema-json-extractor').call({
    startUrls: [{ url: 'https://www.python.org/events/python-events/2209/' }],
    preset: 'event',
    anthropicApiKey: process.env.ANTHROPIC_API_KEY,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Python (`pip install apify-client`):

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("brisaworks/schema-json-extractor").call(run_input={
    "startUrls": [{"url": "https://crawlee.dev/blog/crawlee-for-python-v1"}],
    "preset": "article",
    "anthropicApiKey": os.environ["ANTHROPIC_API_KEY"],
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

### Scheduling and integrations

- **Schedules:** save your input as a task and add an Apify schedule, e.g. every morning for price or job checks.
- **Webhooks:** call your app when a run finishes, to load the new rows.
- **Make, Zapier and n8n:** Apify's integrations start a run and pass the rows on, e.g. to Google Sheets or Slack.

#### Related Brisa Works Actors

- [Shopify Products Scraper & Price Tracker](https://apify.com/brisaworks/shopify-products): product data from Shopify stores without AI, from the store's own product feed.
- [RSS Feed Monitor & Reader](https://apify.com/brisaworks/rss-feed-monitor): new articles from feeds; pass their links here with the article preset for summaries and key points.

### FAQ

#### Do I need an Anthropic API key?

Yes, to get data. Claude runs on your own key, so tokens are billed by Anthropic at their list price. Without a key the run still succeeds and returns free page previews (title and the first 500 characters of text), which shows whether a page can be read before you spend anything.

#### What JSON Schema features are supported?

Validation uses the full schema (draft-07 and 2020-12, formats included). Claude's structured outputs accept most of it; numeric and length limits are moved into field descriptions for the model and still enforced by the validator. Recursive schemas and external `$ref`s fall back to plain JSON prompting.

#### Will it make up values?

The model is told to use only what the page states and to return null when a value is missing, and every answer is checked against your schema. Allow `null` in your schema for fields a page may not state. Check samples before relying on the data.

#### Why did a page come back as invalid_output?

Claude's answer did not match your schema even after the retries. The row lists the errors in `validationErrors`, and it is free. Allow `null` where a page may not state a value, loosen formats, or raise `maxRetriesOnInvalid`.

### Limits

- Pages are fetched without a browser: content rendered only by JavaScript is not seen. Pages behind logins are not supported.
- Long pages are cut at `maxPageChars` (the `truncated` flag tells you).
- Recursive schemas and external `$ref`s cannot use structured outputs and run in the slower fallback mode.
- Five pages in parallel, at most one request per second per site.

### Data source

- The pages you supply. Extraction: Anthropic Messages API structured outputs, <https://platform.claude.com/docs/en/build-with-claude/structured-outputs.md> (read 2026-10-14: unsupported schema features return a 400; objects need `additionalProperties: false`; `claude-haiku-5-5` supported; complexity limits re-read 2026-10-22). Model prices from Anthropic's pricing page (<https://platform.claude.com/docs/en/about-claude/pricing.md>) as of 2026-10-22.
- Example pages: Books to Scrape (<https://books.toscrape.com/>) and Real Python's fake job board (<https://realpython.github.io/fake-jobs/>), both made for scraping practice; python.org's events calendar; the Crawlee blog.

### Privacy

Page text is sent to Anthropic under your own API account (Anthropic does not train on API inputs under its commercial terms). Extract personal data only where you have a lawful basis; the Actor stores nothing after the run.

### Support

Open an issue on the Actor's Issues tab; issues are answered within a few days and fixed within 14 days.

# Actor input Schema

## `startUrls` (type: `array`):

Pages to extract from. Each page is fetched once (no crawling). The example is a page of Books to Scrape, a demo shop built for scraping practice.

## `preset` (type: `string`):

A ready-made schema for a common page type, used when the JSON Schema field below is empty. Product: name, brand, SKU, price, currency, stock, rating, reviews. Job: title, company, location, remote, salary range, date posted, skills. Event: name, dates, venue, city, country, online, price. Article: headline, authors, dates, publisher, summary, key points. Your own JSON Schema always wins over a preset.

## `jsonSchema` (type: `object`):

Your own JSON Schema (draft 2020-12 / draft-07) for the record you want per page. Leave empty to use the preset above; when both are set, this schema wins. Every result is validated against it; add a "description" to each field to guide the model.

## `anthropicApiKey` (type: `string`):

Your Anthropic API key (console.anthropic.com). Claude usage is billed to your Anthropic account. Without a key the run returns free page previews only.

## `model` (type: `string`):

Model ID. claude-haiku-5-5 is fast and cheap; use claude-sonnet-5-5 for hard pages.

## `instructions` (type: `string`):

Optional guidance, e.g. "prices in EUR as numbers" or "only the main product, not related items".

## `maxPageChars` (type: `integer`):

Longer pages are cut to this many characters of text (the output's truncated flag tells you).

## `maxRetriesOnInvalid` (type: `integer`):

How many times the model is shown the validation errors and asked to fix its JSON.

## `respectRobotsTxt` (type: `boolean`):

Skip pages the site's robots.txt disallows.

## `includePageText` (type: `boolean`):

Also return the page text that was sent to the model.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html"
    }
  ],
  "preset": "product",
  "model": "claude-haiku-5-5",
  "maxPageChars": 60000,
  "maxRetriesOnInvalid": 1,
  "respectRobotsTxt": true,
  "includePageText": false
}
```

# Actor output Schema

## `results` (type: `string`):

One row per result, in the dataset (overview view).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html"
        }
    ],
    "preset": "product"
};

// Run the Actor and wait for it to finish
const run = await client.actor("brisaworks/schema-json-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html" }],
    "preset": "product",
}

# Run the Actor and wait for it to finish
run = client.actor("brisaworks/schema-json-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html"
    }
  ],
  "preset": "product"
}' |
apify call brisaworks/schema-json-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,brisaworks/schema-json-extractor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rixaRUPHj8YzvLDSG/builds/6zDbCti8jic6rXsoy/openapi.json
