Skip to main content
POST /v1/products/resolve-from-html resolves one product from the page HTML you submit — typically captured from the product page your user is viewing in your client application — and returns the same source-aware MerchantProductUrlLookupResponse as Product Lookup, with source: "client_html". Octogen never reads its index and never fetches anything: the response is derived entirely from the document you send. The request is stateless — nothing is cached and nothing is stored. Extraction is the same deterministic pass the on-demand lookup path uses: JSON-LD schema.org/Product first, then Open Graph tags, then plain HTML meta. There is no JavaScript rendering and no inference — capture the live DOM rather than the raw server response. See the guide for capture mechanics and timing.
Call this endpoint from your backend only. Your platform API key is an organization-scoped secret — never embed it in code that runs on your users’ devices. Relay captures through your own server: user's browser → your backend → api.octogen.ai.

Request

Body parameters

string
required
The product page HTML, at most 5 MiB. This is the same size bound Octogen’s own live-fetch path enforces, so any page that path could retrieve is submittable. The raw request body is capped at 8 MiB; larger requests are rejected with 413.
string
Source URL of the page. Recommended on every request — your client has location.href at capture time. It anchors relative image URLs and selects the matching JSON-LD product node on multi-product pages, exactly as the final fetched URL does on the lookup path. The field is optional so HTML can still resolve when its source page is unknown: in that case the page must declare its own canonical URL (JSON-LD url, og:url, or link rel="canonical") or resolution fails with 404 product_not_found; relative image URLs are dropped and the response carries a source_url_missing warning.

Example

In the client application, the capture is two values read while the user is on the product page — serialize the live DOM, not the server response:
To build the request body from a saved HTML file (for example, while testing), let jq handle the JSON escaping:

Response

The response reuses the lookup envelope, so a client that already handles source: "on_demand" lookup results parses it without new fields to learn:
Differences from lookup responses, all following from “you supplied the bytes”:

Warnings

Errors

See Error handling for the general error envelope and retry guidance.