Technical guide · reviewed September 2026

How to extract JSON-LD structured data from a website

Parse schema.org blocks from permitted public pages

JSON-LD is JSON embedded in a page, usually in a <script type="application/ld+json"> element. It can describe products, articles, breadcrumbs, organizations, and other entities. Treat it as publisher-provided structured data: useful for discovery, but not automatically complete, current, or authoritative for every field.

Inspect a block in DevTools

For a one-off check on a page you are allowed to inspect, parse every block and keep malformed entries separate instead of letting one bad block abort the whole result.

const blocks = [...document.querySelectorAll('script[type="application/ld+json"]')];
const parsed = blocks.flatMap((element, index) => {
  try { return [{ index, value: JSON.parse(element.textContent) }]; }
  catch { return [{ index, error: 'invalid_json' }]; }
});
console.log(JSON.stringify(parsed, null, 2));

Use the page’s visible content and the schema vocabulary documented at Schema.org when deciding how to normalize a field. Do not assume that a schema block proves the value is visible, available, or eligible for a search feature.

Why raw HTTP and browser output can differ

Some sites include JSON-LD in the initial response; others insert it after JavaScript runs. Compare a raw response with the DOM after a normal browser load before selecting your method. If the required public block is client-rendered, a browser-enabled request can help.

// Raw HTTP: this synthetic response may contain no JSON-LD.
const raw = await fetch('https://demo.example/products/widget');
const html = await raw.text();
console.log(html.includes('application/ld+json'));

// Browser DOM: the page may add a block after scripts run.
console.log(document.querySelectorAll('script[type="application/ld+json"]').length);

Extract with ExtractAPI

ExtractAPI parses valid JSON-LD blocks from the page and returns them in data.structuredData. The field name is structuredData, not jsonld; malformed blocks are skipped and response-size limits still apply.

curl -X POST https://extractapi.app/v1/extract \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://demo.example/products/widget","javascript":true}'

Here is a synthetic, shortened response:

{
  "status": "ok",
  "url": "https://demo.example/products/widget",
  "data": {
    "title": "Widget Pro | Demo Store",
    "structuredData": [
      {
        "@context": "https://schema.org",
        "@type": "Product",
        "name": "Widget Pro",
        "offers": {"@type":"Offer","price":"49.00","priceCurrency":"USD"}
      },
      {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": []
      }
    ],
    "mainContent": "Widget Pro In stock $49.00"
  }
}

Normalize without losing provenance

Keep the original block, source URL, extraction time, and schema type alongside normalized fields. A product can have multiple offers or variants, and a page can publish more than one entity.

function productOffers(structuredData) {
  return structuredData
    .filter(block => block && block['@type'] === 'Product')
    .flatMap(product => {
      const offers = Array.isArray(product.offers) ? product.offers : [product.offers];
      return offers.filter(Boolean).map(offer => ({
        name: product.name || null,
        price: offer.price ?? null,
        currency: offer.priceCurrency ?? null
      }));
    });
}

Common failure modes

Security boundary: only inspect public pages your workflow is authorized to read. Do not send cookies, login credentials, API keys, extracted private content, or verification tokens in a request.

FAQ

Does every page publish JSON-LD?

No. A page may use microdata, RDFa, visible HTML only, or no structured data. A missing array is a valid result.

Can JSON-LD be trusted as the current price?

Not by itself. Validate the page, timestamp, currency, variant, availability, and visible value required by your use case.

Does ExtractAPI return JSON-LD from JavaScript-rendered pages?

It can return valid blocks present in the rendered DOM when browser mode succeeds. Protected pages, failed dependencies, limits, and malformed blocks can still produce no structured data.

Get a free API key