跳转到主要内容

/json - Capture structured data using AI

The /json endpoint extracts structured data from a webpage. You can specify the expected output using either a prompt or a response_format parameter which accepts a JSON schema. The endpoint returns the extracted data in JSON format.

:::note[Note]

By default, the /json endpoint leverages Workers AI for data extraction using @cf/meta/llama-3.3-70b-instruct-fp8-fast. Using this endpoint incurs usage on Workers AI, which you can monitor in the Workers AI Dashboard. To use a different model, refer to Using a custom model (BYO API Key).

:::

Endpoint

https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-run/json

Required fields

You must provide either url or html:

  • url (string)
  • html (string)

And at least one of:

  • prompt (string), or
  • response_format (object with a JSON Schema)

Common use cases

  • Extract product info (title, price, availability) or listings (jobs, rentals)
  • Normalize article metadata (title, author, publish date, canonical URL)
  • Convert unstructured pages into typed JSON for downstream pipelines

Basic usage

With a Prompt and JSON schema

curl

This example captures webpage data by providing both a prompt and a JSON schema. The prompt guides the extraction process, while the JSON schema defines the expected structure of the output.

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-run/json' \
  -H 'authorization: Bearer <apiToken>' \
  -H 'content-type: application/json' \
  -d '{
  "url": "https://developers.cloudflare.com/",
  "prompt": "Get me the list of AI products",
  "response_format": {
    "type": "json_schema",
    "json_schema": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "link": {
                  "type": "string"
                }
              },
              "required": [
                "name"
              ]
            }
          }
        }
      }
  }
}'
{
	"success": true,
	"result": {
		"products": [
			{
				"name": "Build a RAG app",
				"link": "https://developers.cloudflare.com/workers-ai/tutorials/build-a-retrieval-augmented-generation-ai/"
			},
			{
				"name": "Workers AI",
				"link": "https://developers.cloudflare.com/workers-ai/"
			},
			{
				"name": "Vectorize",
				"link": "https://developers.cloudflare.com/vectorize/"
			},
			{
				"name": "AI Gateway",
				"link": "https://developers.cloudflare.com/ai-gateway/"
			},
			{
				"name": "AI Playground",
				"link": "https://playground.ai.cloudflare.com/"
			}
		]
	}
}

TypeScript SDK

Below is an example using the TypeScript SDK:

import Cloudflare from "cloudflare";

const client = new Cloudflare({
	apiToken: process.env["CLOUDFLARE_API_TOKEN"], // This is the default and can be omitted
});

const json = await client.browserRendering.json.create({
	account_id: process.env["CLOUDFLARE_ACCOUNT_ID"],
	url: "https://developers.cloudflare.com/",
	prompt: "Get me the list of AI products",
	response_format: {
		type: "json_schema",
		json_schema: {
			type: "object",
			properties: {
				products: {
					type: "array",
					items: {
						type: "object",
						properties: {
							name: {
								type: "string",
							},
							link: {
								type: "string",
							},
						},
						required: ["name"],
					},
				},
			},
		},
	},
});
console.log(json);

Workers binding

interface Env {
	BROWSER: BrowserRun;
}

export default {
	async fetch(request, env): Promise<Response> {
		return await env.BROWSER.quickAction("json", {
			url: "https://developers.cloudflare.com/",
			prompt: "Get me the list of AI products",
			response_format: {
				type: "json_schema",
				json_schema: {
					type: "object",
					properties: {
						products: {
							type: "array",
							items: {
								type: "object",
								properties: {
									name: { type: "string" },
									link: { type: "string" },
								},
								required: ["name"],
							},
						},
					},
				},
			},
		});
	},
} satisfies ExportedHandler<Env>;

With only a prompt

In this example, only a prompt is provided. The endpoint will use the prompt to extract the data, but the response will not be structured according to a JSON schema. This is useful for simple extractions where you do not need a specific format.

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-run/json' \
  -H 'authorization: Bearer <apiToken>' \
  -H 'content-type: application/json' \
  -d '{
    "url": "https://developers.cloudflare.com/",
    "prompt": "get me the list of AI products"
  }'
{
	"success": true,
	"result": {
		"AI Products": [
			"Build a RAG app",
			"Workers AI",
			"Vectorize",
			"AI Gateway",
			"AI Playground"
		]
	}
}

With only a JSON schema (no prompt)

In this case, you supply a JSON schema via the response_format parameter. The schema defines the structure of the extracted data.

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-run/json' \
  -H 'authorization: Bearer <apiToken>' \
  -H 'content-type: application/json' \
  -d '{
	"url": "https://developers.cloudflare.com/",
	"response_format": {
		"type": "json_schema",
		"json_schema": {
			"type": "object",
			"properties": {
			"products": {
				"type": "array",
				"items": {
				"type": "object",
				"properties": {
					"name": {
					"type": "string"
					},
					"link": {
					"type": "string"
					}
				},
				"required": [
					"name"
				]
				}
			}
			}
		}
    }
  }'
{
	"success": true,
	"result": {
		"products": [
			{
				"name": "Workers",
				"link": "https://developers.cloudflare.com/workers/"
			},
			{
				"name": "Pages",
				"link": "https://developers.cloudflare.com/pages/"
			},
			{
				"name": "R2",
				"link": "https://developers.cloudflare.com/r2/"
			},
			{
				"name": "Images",
				"link": "https://developers.cloudflare.com/images/"
			},
			{
				"name": "Stream",
				"link": "https://developers.cloudflare.com/stream/"
			},
			{
				"name": "Build a RAG app",
				"link": "https://developers.cloudflare.com/workers-ai/tutorials/build-a-retrieval-augmented-generation-ai/"
			},
			{
				"name": "Workers AI",
				"link": "https://developers.cloudflare.com/workers-ai/"
			},
			{
				"name": "Vectorize",
				"link": "https://developers.cloudflare.com/vectorize/"
			},
			{
				"name": "AI Gateway",
				"link": "https://developers.cloudflare.com/ai-gateway/"
			},
			{
				"name": "AI Playground",
				"link": "https://playground.ai.cloudflare.com/"
			},
			{
				"name": "Access",
				"link": "https://developers.cloudflare.com/cloudflare-one/access-controls/policies/"
			},
			{
				"name": "Tunnel",
				"link": "https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/"
			},
			{
				"name": "Gateway",
				"link": "https://developers.cloudflare.com/cloudflare-one/traffic-controls/"
			},
			{
				"name": "Browser Isolation",
				"link": "https://developers.cloudflare.com/cloudflare-one/remote-browser-isolation/"
			},
			{
				"name": "Replace your VPN",
				"link": "https://developers.cloudflare.com/learning-paths/replace-vpn/concepts/"
			}
		]
	}
}

Advanced usage

:::note[Looking for more parameters?] Visit the Browser Run API reference for all available parameters, such as setting HTTP credentials using authenticate, setting cookies, and customizing load behavior using gotoOptions. :::

Using a custom model (BYO API Key)

Browser Run can use a custom model for which you supply credentials. List the model(s) in the custom_ai array:

  • model should be formed as <provider>/<model_name> and the provider must be one of these supported providers.
  • authorization is the bearer token or API key that allows Browser Run to call the provider on your behalf.

This example uses the custom_ai parameter to instruct Browser Run to use a Anthropic's Claude Sonnet 4 model. The prompt asks the model to extract the main <h1> and <h2> headings from the target URL and return them in a structured JSON object.

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-run/json' \
  -H 'authorization: Bearer <apiToken>' \
  -H 'content-type: application/json' \
  -d '{
  "url": "http://demoto.xyz/headings",
  "prompt": "Get the heading from the page in the form of an object like h1, h2. If there are many headings of the same kind then grab the first one.",
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "type": "object",
      "properties": {
        "h1": {
          "type": "string"
        },
        "h2": {
          "type": "string"
        }
      },
      "required": [
        "h1"
      ]
    }
  },
  "custom_ai": [
    {
      "model": "anthropic/claude-sonnet-4-20250514",
      "authorization": "Bearer <ANTHROPIC_API_KEY>"
    }
  ]
}'
{
	"success": true,
	"result": {
		"h1": "Heading 1",
		"h2": "Heading 2"
	}
}

Using a custom model with fallbacks

You may specify multiple models to provide automatic failover. Browser Run will attempt the models in order until one succeeds. To add failover, list additional models in the custom_ai array.

In this example, Browser Run first calls Anthropic's Claude Sonnet 4 model. If that request returns an error, it automatically retries with Meta Llama 3.3 70B from Workers AI, then OpenAI's GPT-4o.

"custom_ai": [
  {
    "model": "anthropic/claude-sonnet-4-20250514",
    "authorization": "Bearer <ANTHROPIC_API_KEY>"
  },
  {
    "model": "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "authorization": "Bearer <CLOUDFLARE_AUTH_TOKEN>"
  },
{
    "model": "openai/gpt-4o",
    "authorization": "Bearer <OPENAI_API_KEY>"
  }
]

Troubleshooting

JSON extraction returns null or empty results

If the /json endpoint returns null or empty results:

  • Provide a clear prompt — Be specific about what data to extract and where it appears on the page (for example, "Extract the product name, price, and description from the main product section").
  • Define a response schema — Use response_format with a JSON schema to enforce the expected output structure.
  • Use a custom model — If the default Workers AI model does not produce the desired results, use the custom_ai parameter to specify a different model. Refer to Using a custom model (BYO API Key) for details.