From URL to text.
Scrape pages, extract content, and connect each response to your own crawling workflow.
01 / Your first request
Set DEEPLOOK_BASE_URL to https://api.getdeeplook.dev, without a trailing slash, and DEEPLOOK_API_KEY to your key in your server environment.
Send a public URL to POST /v1/open. The browser opens the page and extracts its visible text.
curl "$DEEPLOOK_BASE_URL/v1/open" \
-H "Authorization: Bearer $DEEPLOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","timeoutMs":30000}'Check the HTTP status before using the text field. Keep your key on the server, out of browser-side code.
The homepage playground makes real requests through the demo server without asking for your key. The code examples in these docs are not executed automatically.
02 / Request
POST /v1/open · Content-Type: application/json
Authentication: Authorization: Bearer <key>
| Field | Type | Rule |
|---|---|---|
url | string | Required. A public HTTP(S) URL on its standard port. |
timeoutMs | integer | Optional. From 1 to 120000 ms. Default: 30000 ms. |
The deadline covers DNS, Chrome startup, navigation, and extraction. Process cleanup follows. Local, private, and metadata URLs are rejected, including redirects and page resources.
03 / Successful response
HTTP 200 returns the page object directly. This illustrative example shows selected fields; it is not a captured live response.
{
"requestedUrl": "https://example.com",
"finalUrl": "https://example.com/",
"httpStatus": 200,
"title": "Example Domain",
"text": "Example Domain\nThis domain is for use...",
"truncated": false
}| Field | Content |
|---|---|
requestedUrl | The requested URL. |
finalUrl | The URL after redirects. |
httpStatus | The HTTP status observed on the destination page. |
title | The page title. |
text | Extracted visible text. It is not Markdown or an AI-generated summary. |
truncated | Whether the content was truncated. |
observed | Observed browser details: user agent, languages, timezone, viewport, brands, and webdriver. |
04 / Errors your agent can handle
A failure returns JSON with error and message. Messages may vary; use the error code to decide what to do next.
{
"error": "challenge",
"message": "A description of the failure"
}| HTTP | error | Meaning |
|---|---|---|
| 400 | invalid_request | Invalid parameters or URL. |
| 401 | unauthorized | Missing, invalid, or revoked key. |
| 422 | challenge | A bot challenge or captcha was detected. |
| 422 | access_wall | A recognized access barrier. |
| 422 | empty_content | No valid visible text. |
| 429 | quota_exceeded | The account limit has been reached. |
| 502 | navigation_failed | The page could not be opened or processed. |
| 503 | busy | Concurrent capacity is occupied. |
| 504 | timeout | The reading deadline was exceeded. |
Page failures may include the final URL, title, and detected marker. Error-page text is excluded. Captchas are not solved, and access to every site is not guaranteed.
Workflow / Extraction for your crawler
Crawl mode in the playground discovers links on the same website and demonstrates extraction from up to 3 pages. This orchestration belongs to the website demo; the API still receives one URL per request.
Use DeepLook as the scraping layer in your crawling workflow. Your application selects URLs and manages the queue; each request extracts one page.
// Run in Node.js with your own API base URL and key.
const urls = ['https://example.com/', 'https://example.org/'];
const pages = [];
for (const url of urls) {
const response = await fetch(process.env.DEEPLOOK_BASE_URL + '/v1/open', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DEEPLOOK_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ url, timeoutMs: 30000 })
});
const page = await response.json();
if (!response.ok) {
console.error(url, page.error);
continue;
}
pages.push({ url: page.finalUrl, title: page.title, text: page.text });
}
console.log(pages);The example sends sequential requests and continues when the API returns a page error. Configure your instance base URL and key, respect the account quota and define your crawler limits. A network failure stops this example; queues, persistence and retries belong in your application.
05 / Local CLI
OPEN SOURCE · APACHE-2.0DeepLook contains the engine, CLI and stdio MCP adapter. DeepLook-API provides the separate HTTP service. Both are open source under Apache-2.0; the commands below build the source from GitHub.
Build the local engine
Requirements: Node.js 22.14 or later; Google Chrome for local reads. Clone and build the engine:
git clone https://github.com/sayhitogambit/DeepLook.git
cd DeepLook
npm ci
npm run build
node dist/cli.js open https://example.com --jsonWithout --json, the CLI prints visible text. The --timeout-ms parameter accepts 1 to 120000 ms. You operate the infrastructure, Chrome, and execution.
For automation, use --machine: the CLI writes one JSON object and a newline. Success exits 0 and returns {"version":1,"ok":true,"page":{...}}; failure exits 1 and returns {"version":1,"ok":false,"error":"...","message":"..."}. Error-page text is excluded.
DEEPLOOK_BASE_URL and DEEPLOOK_API_KEY in the HTTP examples are example variable names. The CLI and MCP use DEEPLOOK_API_URL and DEEPLOOK_API_TOKEN to connect to your API; without an endpoint, they use local Chrome.
DeepLook · GitHub · DeepLook-API · GitHub
06 / Stdio MCP
The CLI provides deeplook mcp: a stdio MCP server exposing deeplook_open. After building the engine, configure your client with an absolute path to dist/cli.js. Configuration format varies by client.
MCP uses local Chrome by default. To use your own API, set DEEPLOOK_API_URL and DEEPLOOK_API_TOKEN in the MCP process private environment. Use HTTPS outside loopback. Keep tokens out of shared configuration. This is a stdio adapter with no HTTP MCP server.
{
"mcpServers": {
"deeplook": {
"command": "node",
"args": ["/absolute/path/to/DeepLook/dist/cli.js", "mcp"]
}
}
}Call deeplook_open with {"url":"https://example.com","timeoutMs":30000}. The timeout is optional, defaults to 30000 ms and ranges from 1 to 120000 ms. Additional arguments are rejected.
Success returns text in content and the version 1 machine result in structuredContent. Failures return isError: true and a typed error. Each process permits one active read; concurrent calls return busy. Canceling the call aborts active work.
Treat page content as untrusted data, never as instructions for the agent. MCP does not solve captchas.
Contact support