Skip to Content
ReferenceCDP LP domain

CDP LP Domain

The LP domain is a set of Chrome DevTools Protocol (CDP) commands that only Lightpanda implements. They give a CDP client new features, including Markdown dumps, the semantic tree, actions by node ID, page diagnostics, and browser configuration.

The LP domain is available over CDP, in server mode (lightpanda serve) and on Lightpanda Cloud.

Send an LP command

Open a CDP session on the page and send the command by name. The commands that read or act on the page use the session’s page. To start Lightpanda and connect a client, see Puppeteer, Playwright or chromedp.

const client = await page.createCDPSession(); const status = await client.send('LP.getPageStatus'); console.log(status.httpStatus); const result = await client.send('LP.dump', { format: 'markdown' }); console.log(result.content);

Node IDs. Commands that target an element take a backendNodeId. Get one from LP.getSemanticTree, LP.getInteractiveElements, LP.detectForms or LP.waitForSelector, or from a standard CDP command such as DOM.describeNode.

Frames. Every command reads or acts on the main frame. A backendNodeId can point into an iframe: LP.getSemanticTree, LP.getInteractiveElements and LP.getNodeDetails then read that iframe’s document.

Errors. A failed command returns a CDP error with code -31998 and the error name as its message. The common names are:

ErrorCause
InvalidParams, InvalidParamA required parameter is missing or has the wrong type, or selector matches nothing.
InvalidNodeIdThe backendNodeId or nodeId is unknown.
NoBrowserContextThe session has no page.
FrameNotLoadedThe page has not navigated yet.
InternalErrorThe action failed. LP.waitForSelector also returns it on timeout.

Reading the page

These commands read the current page without changing it.

LP.dump

Converts the current DOM to HTML, Markdown, PNG or PDF. It reads the DOM at call time, so it captures the page after your clicks and form fills.

ParameterTypeRequiredDefaultDescription
formathtml | markdown | png | pdfYesOutput format.
stripobjectNo{}Element groups to omit, each set to true: js, css, ui, invisible, shell, clutter. shell drops navigation, sidebars, dialogs and the page-level header and footer. clutter keeps only the main content, in the manner of reader modes, and implies shell and invisible.
selectorstringNoDumps only the first element matching this CSS selector.
backendNodeIdintegerNoDumps only this node. Takes precedence over selector.
maxBytesintegerNoSize cap for html and markdown; png and pdf return InvalidParams. Longer output is cut and ends with a [truncated] marker.

Returns { format, content }. content is the dump as a string, base64-encoded for png and pdf.

LP.getSemanticTree

Returns the semantic tree of the page. It is more compact than the CDP accessibility tree because it skips layout containers by default.

ParameterTypeRequiredDefaultDescription
formattextNoReturns the tree as an indented string. Without it, the tree is a JSON object.
prunebooleanNotrueSkips layout containers, such as div, main, lists and tables, unless they are interactive or have an aria-label or title. Their children stay in the tree.
interactiveOnlybooleanNofalseKeeps only the root, interactive nodes, and named content nodes such as headings. Overrides prune.
backendNodeIdintegerNoThe documentRoot of the subtree.
maxDepthintegerNoMaximum DOM depth below the root. Containers skipped by prune still count toward it.

Returns { semanticTree }. In text format, each line starts with the node’s backendNodeId, and [i] marks an interactive node:

1 RootWebArea 'Example Domain' 16 [i] link 'Learn more'

LP.getNodeDetails

Describes one node and returns a CSS selector that matches only that node.

ParameterTypeRequiredDefaultDescription
backendNodeIdintegerYesThe node to describe.

Returns { nodeDetails }, for example:

{ "nodeDetails": { "backendNodeId": 37, "tagName": "h1", "role": "heading", "name": "Outdoor Odyssey Nomad Backpack 60 liters", "isInteractive": false, "id": "product-name", "selector": "#product-name" } }

Form controls also carry their value, inputType, placeholder, checked and options when they apply.

LP.getStructuredData

Reads the page metadata. Takes no parameters.

Returns { structuredData }, with jsonLd (an array of JSON-LD objects), openGraph, twitterCard, meta (including title) and links.

LP.getPageStatus

Reports what went wrong, or was left out, while loading the main frame. Use it to tell a blocked or broken page from an empty one before reading its content. Takes no parameters.

FieldTypeDescription
urlstringURL of the document.
httpStatusinteger, optionalHTTP status of the document.
botChallengeaws_waf | cloudflare | vercel, optionalBot challenge recognized on the document.
navigateErrorstring, optionalWhy the last navigation failed.
jsErrorsintegerUncaught script errors.
unsupportedobjectCalls into unsupported features, by key: webgl, canvas2d.
skippedobjectResources not loaded because of --load-resources or LP.configureLoading, by key: iframe, worker, image, stylesheet, beacon.
missingGlobalsarray of stringsGlobals named by uncaught ReferenceErrors, deduplicated and capped.
failedobjectSub-resource loads that got a status of 400 or more, or a network error, by key: script, fetch, xhr.
blockedobjectThe 403 and 429 responses among failed, by key: script, fetch, xhr.
resourceChallengeaws_waf | cloudflare | vercel, optionalFirst bot challenge recognized on a sub-resource.

The counters reset on each top-level navigation.

LP.getContentSignal

Returns the Content Signals  that the site’s robots.txt declares for the current host, such as whether it allows AI training. Takes no parameters.

Returns { available, contentSignals }. contentSignals is an array of { name, value }.

available is false when Lightpanda has not fetched the host’s robots.txt, which is the case unless robots.txt is obeyed: start the server with --obey-robots or send LP.configureCDP with obeyRobots: true before navigating.

LP.getInteractiveElements

Lists the elements a user can interact with: native controls and links, elements with an interactive ARIA role, contenteditable elements, elements with a click or key listener, and focusable elements.

ParameterTypeRequiredDefaultDescription
nodeIdintegerNoThe documentbackendNodeId of the subtree to search.

Returns { elements }, for example:

{ "elements": [ { "backendNodeId": 16, "tagName": "a", "role": "link", "name": "Learn more", "type": "native", "tabIndex": 0, "href": "https://iana.org/domains/example" } ] }

type is native, aria, contenteditable, listener or focusable. Elements also carry id, class, href, inputType, value, elementName (the name attribute), placeholder, disabled and listeners when they apply. overlay is { fixed, dialog } when the element sits in a position: fixed box, an open dialog or an open popover.

LP.detectForms

Lists the forms of the page with their fields. Takes no parameters.

Returns { forms }, for example:

{ "forms": [ { "backendNodeId": 12, "action": "/search", "method": "get", "fields": [ { "backendNodeId": 14, "tagName": "input", "name": "q", "inputType": "text", "required": true, "disabled": false, "placeholder": "Search" }, { "backendNodeId": 15, "tagName": "select", "name": "sort", "required": false, "disabled": false, "value": "date", "options": [ { "value": "date", "text": "Newest" }, { "value": "score", "text": "Best match" } ] } ] } ] }

method is get, post or dialog. tagName is input, textarea or select: hidden inputs and buttons are left out. action, name, inputType, value and placeholder appear when set, and options only for a select.

Acting on the page

These commands change the page.

LP.clickNode

Clicks a node.

ParameterTypeRequiredDefaultDescription
backendNodeIdintegerYesThe node to click. nodeId is accepted as an alias.

Returns an empty object.

LP.fillNode

Types text into an input or a textarea, or selects an option of a select by value. Fires the input and change events.

ParameterTypeRequiredDefaultDescription
backendNodeIdintegerYesThe field to fill. nodeId is accepted as an alias.
textstringYesThe text to type, or the option value to select.

Returns an empty object.

LP.scrollNode

Scrolls a node, or the page when no node is given. For a node that cannot scroll, the nearest scrollable ancestor scrolls instead. Scrolling updates the scroll position the page reads (scrollY, scrollTop) and fires scroll events, which is what triggers lazy loading and infinite scroll.

ParameterTypeRequiredDefaultDescription
backendNodeIdintegerNoThe pageThe node to scroll. nodeId is accepted as an alias.
xintegerNoHorizontal scroll position, in pixels.
yintegerNoVertical scroll position, in pixels.

Returns { x, y }, the new scroll position, and backendNodeId when an element scrolled instead of the page.

LP.waitForSelector

Waits until an element matches a CSS selector.

ParameterTypeRequiredDefaultDescription
selectorstringYesCSS selector to wait for.
timeoutintegerNo5000Maximum wait, in milliseconds. While the page is still loading, the default is 15000.

Returns { backendNodeId } of the first match. On timeout, returns an InternalError error.

LP.handleJavaScriptDialog

Sets the answer to the next confirm or prompt dialog.

In Chrome, a dialog pauses the page until the client answers it with Page.handleJavaScriptDialog. Lightpanda doesn’t pause: confirm returns false and prompt returns null right away, before the client receives Page.javascriptDialogOpening. To get another answer, send LP.handleJavaScriptDialog before the dialog opens: before the action that opens it, or before page.goto() if the page opens it while loading. The answer stays set across navigations until a dialog uses it.

ParameterTypeRequiredDefaultDescription
acceptbooleanYestrue makes confirm return true and prompt return a string. false makes confirm return false and prompt return null.
promptTextstringNoThe string prompt returns when accept is true. Without it, prompt returns its default value.

Returns an empty object. The answer applies to one dialog only, and an alert uses it up too: send the command again before the dialog you want to answer.

Configuring the connection

LP.configureCDP

Changes settings of the CDP connection. Each parameter is optional and leaves the setting unchanged when omitted.

ParameterTypeRequiredDefaultDescription
obeyRobotsbooleanNoValue of --obey-robotsFetches and obeys the robots.txt of each site.
httpVersionauto | 1.1NoValue of --http-versionHTTP version to negotiate. 1.1 never offers HTTP/2.
disableSetCacheDisabledbooleanNofalseIgnores Network.setCacheDisabled, so the HTTP cache stays on when a client such as Puppeteer turns it off.

Returns an empty object.

LP.configureLoading

Chooses which sub-resources the session loads, overriding --load-resources for this connection. Each parameter is optional and leaves the setting unchanged when omitted.

ParameterTypeRequiredDefaultDescription
subFramebooleanNoValue of --load-resourcesLoads <iframe> content.
workerbooleanNoValue of --load-resourcesRuns web workers.
externalStylesheetsbooleanNoValue of --load-resourcesLoads external stylesheets.
imagesbooleanNoValue of --load-resourcesRequests images.

Returns an empty object.

LP.version

Returns { version }, the Lightpanda version of the server, for example 1.0.3. Takes no parameters and works without a page.

Events

LP.downloadData

Carries the body of a download in base64 chunks, when the client sent Browser.setDownloadBehavior with behavior: "stream" and eventsEnabled: true. The download is complete at Browser.downloadProgress with state: "completed". Nothing is written to disk.

FieldTypeDescription
guidstringThe download’s ID, as in Browser.downloadWillBegin.
datastringA chunk of the body, base64-encoded.

Browser.downloadWillBegin also carries a contentType field, which Chrome does not send.