NewIntroducing semantic snapshotsPair every capture with structured DOM data →

For pages with no reliable selectors

Describe the fields in a schema and get validated JSON back

Send a page, a sentence about what you want and a JSON Schema, and get back JSON that has already been checked against it.

The problem

Event listings from a hundred venues, product pages from a dozen shops, press releases from every company in a sector. Each site marks its data up differently and changes it without notice, so a selector per site is a maintenance job that never ends.

How domscout handles it

POST /extract takes a url, or the text or HTML you already have, plus a prompt and a JSON Schema. A language model reads the page text and must answer in JSON, and domscout validates that answer against your schema before returning it, so a field of the wrong type or a missing required field never arrives as data. If the first answer misses the schema, the validation error goes back to the model once; a second miss is an unbilled 502. A url is fetched as plain HTTP without running JavaScript, so for a page that builds its content in the browser, capture it as Markdown first and send that as content.

Where it shows up

  • Event, job or listing records from sites that all mark them up differently.
  • Product details from many shops normalised into one shape.
  • Structured fields from text you already hold: emails, notes, exported pages.

The request

POST /extract. /extract starts at Pro and costs 4 credits a request. Fetching the page and the model's answer share an 18-second limit, so sending a bounded excerpt as content leaves more of it for the model. The schema supports a stated subset of JSON Schema, and a keyword outside it is refused with a 400 rather than ignored.

cURL
curl -X POST https://api.domscout.io/extract \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/events/autumn-meetup",
    "prompt": "Extract the event'\''s name, start date, venue and ticket price.",
    "schema": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "startDate"],
      "properties": {
        "name": {"type": "string"},
        "startDate": {"type": "string", "description": "ISO 8601 date"},
        "venue": {"type": ["string", "null"]},
        "ticketPrice": {"type": ["number", "null"]}
      }
    }
  }'
Node.js
const response = await fetch("https://api.domscout.io/extract", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY" },
  body: JSON.stringify({
    url: "https://example.com/events/autumn-meetup",
    prompt: "Extract the event's name, start date, venue and ticket price.",
    schema: {
      type: "object",
      additionalProperties: false,
      required: ["name", "startDate"],
      properties: {
        name: { type: "string" },
        startDate: { type: "string", description: "ISO 8601 date" },
        venue: { type: ["string", "null"] },
        ticketPrice: { type: ["number", "null"] }
      }
    }
  }),
});
const result = await response.json();
console.log(result.data);
Python
import requests

response = requests.post(
    "https://api.domscout.io/extract",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "url": "https://example.com/events/autumn-meetup",
        "prompt": "Extract the event's name, start date, venue and ticket price.",
        "schema": {
            "type": "object",
            "additionalProperties": False,
            "required": ["name", "startDate"],
            "properties": {
                "name": {"type": "string"},
                "startDate": {"type": "string", "description": "ISO 8601 date"},
                "venue": {"type": ["string", "null"]},
                "ticketPrice": {"type": ["number", "null"]}
            }
        }
    },
)
print(response.json()["data"])
Go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	body, _ := json.Marshal(map[string]any{
		"url": "https://example.com/events/autumn-meetup",
		"prompt": "Extract the event's name, start date, venue and ticket price.",
		"schema": map[string]any{
			"type": "object",
			"additionalProperties": false,
			"required": []any{"name", "startDate"},
			"properties": map[string]any{
				"name": map[string]any{"type": "string"},
				"startDate": map[string]any{"type": "string", "description": "ISO 8601 date"},
				"venue": map[string]any{"type": []any{"string", "null"}},
				"ticketPrice": map[string]any{"type": []any{"number", "null"}},
			},
		},
	})
	req, _ := http.NewRequest("POST", "https://api.domscout.io/extract", bytes.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-api-key", "YOUR_API_KEY")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	var result map[string]any
	json.NewDecoder(res.Body).Decode(&result)
	fmt.Println(result["data"])
}
PHP
<?php
$ch = curl_init('https://api.domscout.io/extract');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'x-api-key: YOUR_API_KEY'],
    CURLOPT_POSTFIELDS => json_encode([
        'url' => 'https://example.com/events/autumn-meetup',
        'prompt' => 'Extract the event\'s name, start date, venue and ticket price.',
        'schema' => [
            'type' => 'object',
            'additionalProperties' => false,
            'required' => ['name', 'startDate'],
            'properties' => [
                'name' => ['type' => 'string'],
                'startDate' => ['type' => 'string', 'description' => 'ISO 8601 date'],
                'venue' => ['type' => ['string', 'null']],
                'ticketPrice' => ['type' => ['number', 'null']]
            ]
        ]
    ]),
]);
$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
$result = json_decode($response, true);
print_r($result['data']);
Ruby
require "json"
require "net/http"

response = Net::HTTP.post(
  URI("https://api.domscout.io/extract"),
  {
    url: "https://example.com/events/autumn-meetup",
    prompt: "Extract the event's name, start date, venue and ticket price.",
    schema: {
      type: "object",
      additionalProperties: false,
      required: ["name", "startDate"],
      properties: {
        name: { type: "string" },
        startDate: { type: "string", description: "ISO 8601 date" },
        venue: { type: ["string", "null"] },
        ticketPrice: { type: ["number", "null"] }
      }
    }
  }.to_json,
  "Content-Type" => "application/json",
  "x-api-key" => "YOUR_API_KEY"
)
puts JSON.parse(response.body)["data"]
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Capture {
    public static void main(String[] args) throws Exception {
        String body = """
            {
                "url": "https://example.com/events/autumn-meetup",
                "prompt": "Extract the event's name, start date, venue and ticket price.",
                "schema": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["name", "startDate"],
                    "properties": {
                        "name": {"type": "string"},
                        "startDate": {
                            "type": "string",
                            "description": "ISO 8601 date"
                        },
                        "venue": {"type": ["string", "null"]},
                        "ticketPrice": {"type": ["number", "null"]}
                    }
                }
            }
            """;
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.domscout.io/extract"))
            .header("Content-Type", "application/json")
            .header("x-api-key", "YOUR_API_KEY")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
C#
using System.Net.Http.Json;
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var response = await client.PostAsJsonAsync("https://api.domscout.io/extract", new {
    url = "https://example.com/events/autumn-meetup",
    prompt = "Extract the event's name, start date, venue and ticket price.",
    schema = new {
        type = "object",
        additionalProperties = false,
        required = new[] { "name", "startDate" },
        properties = new {
            name = new { type = "string" },
            startDate = new { type = "string", description = "ISO 8601 date" },
            venue = new { type = new[] { "string", "null" } },
            ticketPrice = new { type = new[] { "number", "null" } }
        }
    }
});
var result = await response.Content.ReadFromJsonAsync<JsonElement>();
Console.WriteLine(result.GetProperty("data"));

Go further

More in Data extraction and search: Crawling a whole site · Structured data from web pages · Semantic search over your content · Content behind clicks · Company research from websites · Evaluation sets from real pages · All use cases

Give your product a browser.

Get clean web content and visual proof into your workflow in minutes.