> For the complete documentation index, see [llms.txt](https://developers.oxylabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.oxylabs.io/products/web-scraper-api/features/custom-parser/getting-started.md).

# Getting started

Learn to use Oxylabs Custom Parser. On this page, you'll find comprehensive examples, tips, and details on what happens if parsing fails.

## How to use Custom Parser <a href="#how-to-use-custom-parser" id="how-to-use-custom-parser"></a>

### Scenario example

Parse the **price of the first product** listed on an e-commerce site, **`https://sandbox.oxylabs.io/products?q=super+mario`**:

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FsyYKUF76MWH5no3UxjZW%2Fimage.png?alt=media&amp;token=9b40f065-61e3-447a-b72e-a68d1cdd385e" alt="" width="375"><figcaption></figcaption></figure>

There are three ways to create a parser. This page walks through the quickest one, OxyCopilot, and the other two are covered on their own pages:

* [Generate parsers with OxyCopilot](#generate-parsers-with-oxycopilot)
* [Generate parsers via API](/products/web-scraper-api/features/custom-parser/generating-parsing-instructions-via-api.md)
* [Write parsing instructions manually](/products/web-scraper-api/features/custom-parser/writing-instructions-manually/tips-for-writing-xpath-expressions.md#how-to-write-parsing-instructions-inlineextension)

### Generate parsers with OxyCopilot

OxyCopilot lets you describe your needs in plain English to **automatically create scrapers and parsers** for a website. Learn the basics by following the steps outlined below and check out [OxyCopilot documentation](/products/web-scraper-api/web-scraper-api-playground/oxycopilot.md#custom-parser-builder) for more information.

{% hint style="success" %}
Open the [**Web Scraper API Playground**](https://dashboard.oxylabs.io/en/api-playground) on our dashboard to access OxyCopilot.
{% endhint %}

{% stepper %}
{% step %}

#### Enter the URL(s)

Click the **OxyCopilot button** at the top-left side and enter up to 3 URLs of the same page type and click **Next**. Let's use this sandbox URL: **`https://sandbox.oxylabs.io/products?q=super+mario`**.

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FFmFBG02HI7hRLK7L2cj5%2Fimage.png?alt=media&amp;token=9aaeebfb-2bad-443e-be66-2570235f3299" alt="" width="545"><figcaption></figcaption></figure>

{% hint style="info" %}
You can also configure the scraper manually by filling in the **Website**, **Scraper**, and **URL** fields at the top, and adjusting **additional parameters** like JavaScript rendering in the left-side menu.
{% endhint %}
{% endstep %}

{% step %}

#### Set up scraper parameters

Next, specify scraper parameters, browser instructions, and enable JavaScript rendering if your target website requires that.

The sandbox page does not need JavaScript rendering, so keep the defaults and click **Next**.&#x20;

{% hint style="info" %}
Rendering matters when the data you want is not in the HTML the server sends but is added by JavaScript after the page loads, as is common for prices, product listings and reviews. Without rendering, Custom Parser only sees the initial HTML, so instructions targeting that data return nothing. Read more about [**JavaScript rendering**](/products/web-scraper-api/features/js-rendering-and-browser-control.md#javascript-rendering).
{% endhint %}

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FnywZ0UXzVmsthQQmIbht%2Fimage.png?alt=media&amp;token=9be92716-53c5-4230-a6ba-b1484c532be7" alt="" width="470"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Write the prompt

Explain the data you want to extract from a page. Make sure to be descriptive and provide the most important information. You can find prompt examples for popular websites in our [OxyCopilot prompts library](https://oxylabs.io/resources/prompts-code-samples).

Paste the following prompt to extract the price of the first product:

```
Parse the price of the first product on the page.
```

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FOG3MoIvtLoulTzaPFq26%2Fimage.png?alt=media&amp;token=3565708a-082c-4e42-b62c-98f60ff73a73" alt="" width="470"><figcaption></figcaption></figure>

Click the **Generate instructions** button to send your prompt.
{% endstep %}

{% step %}

#### Review parsed data and instructions

Once OxyCopilot finishes, you'll see the following window where parsed data is on the right-side:

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2F8Yd8bNBQXPwscHKdSK1U%2Fimage.png?alt=media&amp;token=ce799a13-a229-43b6-9de9-36cfd4873990" alt=""><figcaption></figcaption></figure>

If you want to make any adjustments, you can do so here. Modify the URL(s), refine the prompt, enable JavaScript rendering, or [edit the parsing schema](/products/web-scraper-api/web-scraper-api-playground/oxycopilot.md#step-2-optional-adjust-parsing-schema) to suit your needs. When you update any fields in this window, you can rerun the request by selecting **Start new request**.

You may also **view and directly edit the parsing instructions** here:

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FvW521rQpr277NpSDPSP8%2Fimage.png?alt=media&amp;token=ecf24ec7-a5b6-42bc-877e-79d9187dcf39" alt=""><figcaption></figcaption></figure>

Once you're happy with the result, **Load instructions** to continue.

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2F2bVplkgKW67lmAd7zWS9%2Fimage.png?alt=media&amp;token=5c067a5e-0b0e-4d47-b28d-c96e07deedcf" alt="" width="469"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Save the parser as a preset

You can easily save your parsing instructions as a [parser preset](/products/web-scraper-api/features/custom-parser/parser-presets.md). This lets you reuse the preset in OxyCopilot and with your API requests.

In the Web Scraper API Playground, you can optionally choose the user for which to save the preset. Once you're all set, simply click **Save**:

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FKuZLB7HY6298sZhClts8%2Fimage.png?alt=media&amp;token=f0429fc1-ad0a-4159-bf23-60b0bcccc25e" alt=""><figcaption></figcaption></figure>

A pop-up will appear prompting you to name the preset and add an optional description:

<figure><img src="https://3826932121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBQ7Zf9paoN3FTeGcyfY1%2Fuploads%2FnpBJz2wlknd0kfAR1ayx%2Fimage.png?alt=media&amp;token=3e031dc5-3bd1-49a3-bdb8-81cb1473adc2" alt="" width="333"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Use the preset with API requests

To use a preset with your Web Scraper API requests, set `parse` to `true` and specify the preset name with the `parser_preset` parameter.

**Endpoint:** `POST https://realtime.oxylabs.io/v1/queries`

```json
{
    "source": "universal",
    "url": "https://sandbox.oxylabs.io/products",
    "parse": true,
    "parser_preset": "sandbox_first_product_price"
}
```

Running the request will provide the following JSON output:

```json
{
    "results": [
        {
            "_request": {...},
            "_response": {...},
            "content": {
                "parse_status_code": 12000,
                "price": 91.99
            },
            "created_at": "2026-09-08 11:21:03",
            "is_render_forced": false,
            "job_id": "7503049765014236161",
            "page": 1,
            "parser_preset": "sandbox_first_product_price",
            "parser_type": "preset",
            "session_info": {...},
            "status_code": 200,
            "type": "parsed",
            "updated_at": "2026-09-08 11:21:09",
            "url": "https://sandbox.oxylabs.io/products"
        }
    ]
}

```

{% endstep %}
{% endstepper %}

## Advanced usage

OxyCopilot is the quickest way to create a parser, but every step of it is also available directly through the API:

* **Generate parsing instructions via API** – send a prompt or a JSON schema together with a few example URLs and receive ready-to-use instructions. See [**Generating parsing instructions via API**](/products/web-scraper-api/features/custom-parser/generating-parsing-instructions-via-api.md).
* **Save and manage presets via API** – create, update, list and delete parser presets, and enable self-healing. See [**Parser Presets**](/products/web-scraper-api/features/custom-parser/parser-presets.md).
* **Write parsing instructions manually** – build your own extraction pipeline with XPath and CSS selectors. Start with [**How to write parsing instructions**](/products/web-scraper-api/features/custom-parser/writing-instructions-manually.md), then browse the [**Parsing instruction examples**](/products/web-scraper-api/features/custom-parser/writing-instructions-manually/parsing-instruction-examples.md).

## What happens if parsing fails when using Custom Parser <a href="#what-happens-if-parsing-fails-when-using-custom-parser" id="what-happens-if-parsing-fails-when-using-custom-parser"></a>

If Custom Parser cannot apply one of your instructions, the job still succeeds: the result carries `parse_status_code` `12005` (parsed with warnings) and a `_warnings` list describing which instruction failed and why. You are charged for such results.&#x20;

For example, this request asks for a field whose XPath matches nothing on the page:

```json
{
    "source": "universal",
    "url": "https://sandbox.oxylabs.io/products",
    "parse": true,
    "parsing_instructions": {
        "first_product_price": {
            "_fns": [
                {
                    "_fn": "xpath_one",
                    "_args": [
                        "//div[contains(@class, 'price-wrapper')]/text()"
                    ]
                },
                {
                    "_fn": "amount_from_string"
                }
            ]
        },
        "number_of_reviews": {
            "_fns": [
                {
                    "_fn": "xpath",
                    "_args": [
                        "//this-will-not-match-anything"
                    ]
                },
                {
                    "_fn": "length"
                }
            ]
        }
    }
}
```

The price is parsed normally, the failing field is returned as `null`, with a warning:

```json
{
    "results": [
        {
            "_request": {...},
            "_response": {...},
            "content": {
                "_warnings": [
                    {
                        "_fn": "xpath",
                        "_fn_idx": 0,
                        "_msg": "XPath expressions did not match any data.",
                        "_path": ".number_of_reviews"
                    }
                ],
                "first_product_price": 91.99,
                "number_of_reviews": null,
                "parse_status_code": 12005
            },
            "created_at": "2026-09-08 09:00:40",
            "is_render_forced": false,
            "job_id": "7503014433245923329",
            "page": 1,
            "parser_preset": null,
            "parser_type": "custom",
            "session_info": {...},
            "status_code": 200,
            "type": "parsed",
            "updated_at": "2026-09-08 09:00:44",
            "url": "https://sandbox.oxylabs.io/products"
        }
    ]
}
```

To ignore a failing field instead of receiving a warning, see [**Parsing instruction examples › Error handling**](/products/web-scraper-api/features/custom-parser/writing-instructions-manually/parsing-instruction-examples.md#error-handling).

If Custom Parser encounters an exception and breaks during the parsing operation, it can return  status codes `12002`, `12006`, and `12007`. You will not be charged for these unexpected errors.

Instructions referencing a non-existent function are rejected upon submission and no job is created. The API returns an HTTP `400` error naming the missing function and its path: function `not_a_real_fn` is not defined.

## Status codes <a href="#status-codes" id="status-codes"></a>

See our status codes outlined [**here**](/products/web-scraper-api/response-codes.md#parsers).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.oxylabs.io/products/web-scraper-api/features/custom-parser/getting-started.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
