# Google Lens OCR API: Image to Text and PDF OCR with Word Boxes (`getascraper/google-lens-ocr`) Actor

Turn images and multi-page PDFs into text with Google Lens OCR. Use image URLs, uploaded screenshots, Base64, or Apify storage, or call the Standby REST endpoint. Get word and line boxes, writing direction, translation, and a status per image. From $0.003 per image. Not affiliated with Google.

- **URL**: https://apify.com/getascraper/google-lens-ocr.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Developer tools, AI, MCP servers
- **Features:** Limited permissions, Single-tenant, Server interface
- **Stats:** 184 total users, 51 monthly users, 99.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 listing scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 🔎 Google Lens OCR API: Image to Text and PDF OCR with Word Boxes

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed;margin-bottom:0">
<tr>
<td colspan="2" style="padding:14px 18px;background:#EAF1FB;border:none;border-top:3px solid #1A56C4;border-left:1px solid #B8D4F4;border-right:1px solid #B8D4F4;color:#1C1917;border-radius:10px 10px 0 0">
<span style="font-size:16px;font-weight:700;color:#1C1917">Part of the Google Lens Image-Intelligence Pair.</span> <span style="font-size:15px;color:#57534E">Two focused Actors built on the same engine: pull text out of an image, or find where it appears online.</span>
</td>
</tr>
<tr>
<td colspan="2" style="padding:10px 14px;background:#1A56C4;border:none;border-left:1px solid #B8D4F4;border-right:1px solid #B8D4F4;color:#FFFFFF">
<span style="color:#FFFFFF;font-size:14px;font-weight:700;letter-spacing:0.5px">GOOGLE LENS IMAGE-INTELLIGENCE PAIR</span>
<span style="color:#FFFFFF;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;OCR and reverse image search, built on the same engine</span>
</td>
</tr>
<tr>
<td style="padding:10px 12px;border:none;border-left:1px solid #B8D4F4;border-bottom:1px solid #B8D4F4;vertical-align:top;width:50.0%;background:#EAF1FB;color:#1C1917">
<span style="overflow-wrap:break-word;word-break:break-word"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/jNDbFabbVxMhnQNb4-actor-eoVXILAQvzkbyNVrD-ovfg0C1vJW-CompressJPEG.Online_img%28512x512%29_%2823%29.jpg" width="20" height="20" style="vertical-align:middle;border-radius:4px">&nbsp;<a href="https://apify.com/getascraper/google-lens-ocr" style="color:#1A56C4;text-decoration:none;font-weight:700;font-size:13px">Google Lens OCR</a></span><br>
<span style="color:#1A56C4;font-size:11px;font-weight:700">&#10148; You are here</span>
</td>
<td style="padding:10px 12px;border:none;border-left:1px solid #B8D4F4;border-right:1px solid #B8D4F4;border-bottom:1px solid #B8D4F4;vertical-align:top;width:50.0%;background:#FFFFFF;color:#1C1917">
<span style="overflow-wrap:break-word;word-break:break-word"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/jNDbFabbVxMhnQNb4-actor-IQNVK9GGbkkLndLKu-9wOM9ttWwN-CompressJPEG.Online_img%28512x512%29_%2823%29.jpg" width="20" height="20" style="vertical-align:middle;border-radius:4px">&nbsp;<a href="https://apify.com/getascraper/google-lens-visual-search" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">Google Lens Visual Search</a></span><br>
<span style="color:#57534E;font-size:11px">Reverse image search, web matches, and OCR</span>
</td>
</tr>
</table>
<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;margin-top:0;margin-bottom:0"><tr>
<td style="padding:24px 28px;background:#EAF1FB;border:1px solid #B8D4F4;border-top:none;color:#1C1917">
<span style="font-size:23px;font-weight:800;color:#172033;line-height:1.3">Turn any image or PDF into searchable text in about a second per page.</span><br>
<span style="font-size:15px;color:#3F4B5F;line-height:1.6">Upload a screenshot, paste an image or PDF URL, call a live Standby endpoint for one image, or submit a batch of URLs, Base64 payloads, or Apify key-value store records in a single run.</span>
</td>
</tr></table>
<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;margin-top:0"><tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #B8D4F4;vertical-align:top;border-top:none;color:#1C1917;border-radius:0 0 0 10px">
<span style="font-size:15px;font-weight:800;color:#1A56C4">⚡ No cold start</span><br>
<span style="font-size:12px;color:#3F4B5F">The Standby endpoint answers a single image in about a second.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #B8D4F4;border-left:none;vertical-align:top;border-top:none;color:#1C1917">
<span style="font-size:15px;font-weight:800;color:#1A56C4">📦 Images, PDFs, uploads</span><br>
<span style="font-size:12px;color:#3F4B5F">Image URLs, an uploaded file, multi-page PDFs, Base64 data, or key-value store records.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #B8D4F4;border-left:none;vertical-align:top;border-top:none;color:#1C1917">
<span style="font-size:15px;font-weight:800;color:#1A56C4">🔠 Real geometry</span><br>
<span style="font-size:12px;color:#3F4B5F">Word, line, and paragraph boxes come straight from Google, never estimated.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #B8D4F4;border-left:none;vertical-align:top;border-top:none;color:#1C1917;border-radius:0 0 10px 0">
<span style="font-size:15px;font-weight:800;color:#1A56C4">🌐 Optional translation</span><br>
<span style="font-size:12px;color:#3F4B5F">Request a target language while keeping the original OCR text.</span>
</td>
</tr></table>

Extract text from a single image, a screenshot you upload, a multi-page PDF, or a whole batch, using the same engine behind Google Lens. Call it as a live REST endpoint for one image at a time (no cold start), or submit a batch of image URLs, PDF URLs, Base64 payloads, or Apify key-value store records in one run. Every submitted image and every PDF page returns one correlated result with its status, detected language, dimensions, word count, timing, and any real error.

Use the output for document indexing, searchable archives, translation workflows, content moderation, accessibility pipelines, RAG preparation, and AI agent tool calls.

### 🧾 Sample result

Input: one public photo of a restaurant receipt, `outputDetail` left at its default.

```json
{
    "imageUrl": "https://commons.wikimedia.org/wiki/Special:FilePath/ReceiptSwiss.jpg?width=1000"
}
```

Result row (the per-line `lines` array with boxes is omitted here for length):

```json
{
    "inputId": "single-1",
    "sourceType": "URL",
    "status": "SUCCEEDED",
    "language": "en",
    "fullText": "Berghotel\nGrosse Scheidegg\n3818 Grindelwald\nFamilie R. Müller\nRech. Nr. 4572\n30.07.2007/13:29:17\nBar\nTisch 7/01\n2xLatte Macchiato à\n4.50\nCHF\n9.00\n1xGloki\nà\n5.00\nCHF\n5.00\n1xSchweinschnitzel\nà\n22.00\nCHF\n22.00\n1xChässpätzli\nà\n18.50\nCHF\n18.50\nTotal:\nCHF\n54.50\nIncl. 7.6% MwSt\n54.50\n...",
    "wordCount": 70,
    "imageWidth": 1280,
    "imageHeight": 1707,
    "lineGeometryAvailable": true,
    "wordGeometryAvailable": false,
    "geometryLevel": "LINE"
}
```

#### Copy to your AI assistant

```
getascraper/google-lens-ocr on Apify. Two ways to call it:
1) Standby REST API (no cold start, one image per call): find this Actor's Standby hostname on its
   Standby tab in Apify Console, then GET https://<standby-hostname>/ocr?imageUrl=...&outputDetail=full&token=TOKEN
2) Batch run via the Apify client: ApifyClient("TOKEN").actor("getascraper/google-lens-ocr").call(run_input={"imageUrl": "..."}), then client.dataset(run["defaultDatasetId"]).list_items().items for results.
Key inputs: imageUrl: string (a single image), pdfUrl: string (a PDF, one row per page), outputDetail: string (text_only|lines|full|paragraphs|words), translateTo: string (optional language code). Batch inputs (imageUrls, imagesBase64, imageKvsRecords) also available for many images in one run.
Full actor spec (input schema, output dataset fields, README): GET https://api.apify.com/v2/acts/getascraper~google-lens-ocr/builds/default (Bearer TOKEN) → inputSchema, actorDefinition.storages.dataset, readme.
Get a token: https://console.apify.com/account/integrations
```

### ✨ What this Actor gives you

- **A live Standby endpoint:** Call `GET /ocr?imageUrl=...` for a single image with no container cold start, alongside normal batch runs.
- **Flexible inputs:** One image URL or an uploaded file for the common case, plus bulk URLs, Base64 image data, and Apify key-value store records for batches.
- **PDF OCR:** Give a PDF URL and get one result row per page, with the page number and the PDF's total page count.
- **Stable correlation:** Supply your own `inputId`, or use deterministic IDs assigned in input order.
- **Honest batch rows:** Successful, partial, and failed inputs all remain visible.
- **Source dimensions:** Get the original image width and height when the image can be decoded.
- **Detected language and writing direction:** Know whether text reads left-to-right, right-to-left, or top-to-bottom.
- **Real word, line, and paragraph geometry:** Every box comes directly from Google's own response. Nothing is estimated or interpolated.
- **Detected regions:** Salient regions and objects Google's own response identifies in the image, at no extra cost.
- **Optional translation:** Request a target language while retaining the original OCR text.
- **Bounded concurrency:** Process batches without launching every image request at once.
- **Run summary:** Review submitted, successful, partial, and failed counts in `RUN_SUMMARY`.

### 🎯 Common workflows

- **AI agents and MCP tools:** Call the Standby endpoint as a fast, stateless OCR tool with no run-management overhead.
- **AI and RAG teams:** Turn screenshots and scanned pages into searchable text with source correlation.
- **Automation teams:** Process receipt, label, menu, poster, and document image batches.
- **Localization teams:** Extract original text and request a translated version in the same row.
- **Data operations teams:** Reconcile every input against a clear success, partial, or failure status.
- **Developers:** Use real word-level boxes and writing direction for layout reconstruction and highlighting.

### ⚡ Call it live, or run it as a batch

**For a single image**, call the Standby endpoint directly instead of starting a run. Find this Actor's Standby hostname on its **Standby** tab in Apify Console, then:

```
GET https://<standby-hostname>/ocr?imageUrl=https://example.com/photo.jpg&outputDetail=full&token=YOUR_TOKEN
```

It answers in about a second, since there is no container start-up wait once the Actor is warm.

**For many images**, run the Actor normally:

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0">
<tr>
<td style="padding:16px 14px;width:33%;background:#EAF1FB;border:1px solid #B8D4F4;border-radius:10px 0 0 10px;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#1A56C4;letter-spacing:1px">STEP 1</span><br>
<span style="font-size:14px;font-weight:700;color:#172033">Add your images</span><br>
<span style="font-size:12px;color:#3F4B5F">Paste one image URL or upload a file, add a PDF URL, or open Batch and advanced sources for a URL list, Base64 data, or key-value store records.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EAF1FB;border:1px solid #B8D4F4;border-left:none;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#1A56C4;letter-spacing:1px">STEP 2</span><br>
<span style="font-size:14px;font-weight:700;color:#172033">Pick the detail</span><br>
<span style="font-size:12px;color:#3F4B5F">Choose output detail, an optional translation language, and concurrency.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EAF1FB;border:1px solid #B8D4F4;border-left:none;border-radius:0 10px 10px 0;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#1A56C4;letter-spacing:1px">STEP 3</span><br>
<span style="font-size:14px;font-weight:700;color:#172033">Start and read results</span><br>
<span style="font-size:12px;color:#3F4B5F">Open the dataset for one correlated row per image, or RUN_SUMMARY for run totals.</span>
</td>
</tr>
</table>

### 📥 Input

| Field             | Type    | Required    | Description                                                                                                                                       |
| :---------------- | :------ | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------ |
| `imageUrl`        | string  | Conditional | One public HTTP or HTTPS image URL. This is all most runs need.                                                                                   |
| `imageUrlInputId` | string  | No          | Correlation ID for `imageUrl`. Defaults to `single-1`.                                                                                            |
| `imageFile`       | file    | Conditional | An image uploaded from your computer, such as a screenshot. No hosting needed. Its row uses the ID `upload-1`.                                    |
| `imageUrls`       | array   | Conditional | Bulk URL objects, for batches. Each item can include `url` and `userData.inputId`.                                                                |
| `imagesBase64`    | array   | Conditional | Objects containing `data` and an optional `inputId`. Raw Base64 and image data URIs are accepted.                                                 |
| `imageKvsRecords` | array   | Conditional | Objects containing `key`, optional `storeId`, and optional `inputId`.                                                                             |
| `outputDetail`    | string  | No          | `text_only`, `lines`, `full` (default), `paragraphs` (adds grouping and writing direction), or `words` (adds every word's own box and rotation). |
| `translateTo`     | string  | No          | Target language code such as `es`, `de`, or `pt-BR`.                                                                                              |
| `maxConcurrency`  | integer | No          | Images processed at once in a batch run, from 1 to 10.                                                                                            |
| `pdfUrl`          | string  | Conditional | One public PDF URL. Every page is OCR'd into its own result row.                                                                                  |
| `pdfUrls`         | array   | Conditional | Bulk PDF URL objects. Each item can include `url` and `userData.inputId`.                                                                         |
| `maxPdfPages`     | integer | No          | Most pages to process per PDF, from 1 to 100. Defaults to 20.                                                                                     |

At least one of `imageUrl`, `imageFile`, `imageUrls`, `imagesBase64`, `imageKvsRecords`, `pdfUrl`, or `pdfUrls` must be provided.

To OCR a screenshot that is only on your computer, use **Upload an image** in the input form. Clear the prefilled Image URL if you only want the uploaded file processed.

#### URL batch example

```json
{
    "imageUrls": [
        {
            "url": "https://tesseract.projectnaptha.com/img/eng_bw.png",
            "userData": { "inputId": "poem-page-1" }
        },
        {
            "url": "https://example.com/document-page-2.png",
            "userData": { "inputId": "document-page-2" }
        }
    ],
    "outputDetail": "full",
    "translateTo": "es",
    "maxConcurrency": 3
}
```

#### Apify storage example

```json
{
    "imageKvsRecords": [
        {
            "storeId": "my-image-store",
            "key": "receipts/july-001.png",
            "inputId": "receipt-july-001"
        }
    ],
    "outputDetail": "lines"
}
```

The default key-value store is used when `storeId` is omitted. A storage record can contain binary image data, a Base64 string, or a JSON object with a Base64 `data` field.

#### PDF example

Give a PDF URL and get one result row per page. Each row carries its `page` number, the PDF's total `pageCount`, and the `sourcePdfUrl`. Use `maxPdfPages` to cap long documents.

```json
{
    "pdfUrl": "https://example.com/report.pdf",
    "maxPdfPages": 20,
    "outputDetail": "full"
}
```

#### Recurring document OCR workflow

Use the same `imageUrls` input from an Apify schedule. Keep `inputId` stable so downstream systems can reconcile each image across runs.

```json
{
    "imageUrls": [
        {
            "url": "https://example.com/invoices/2026-08-01.png",
            "userData": { "inputId": "invoice-2026-08-01" }
        }
    ],
    "outputDetail": "full"
}
```

### 📤 Output

The Actor writes one row for each submitted image, and one row per page for PDF inputs. This abbreviated example comes from the public Tesseract sample image:

```json
{
    "inputId": "sample-1",
    "sourceType": "URL",
    "sourceReference": "https://tesseract.projectnaptha.com/img/eng_bw.png",
    "imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
    "status": "SUCCEEDED",
    "language": "en",
    "fullText": "Mild Splendour of the various-vested Night!\nMother of wildly-working visions! hail!\nI watch thy gliding, while with watery light\nThy weak eye glimmers through a fleecy veil;\nAnd when thou lovest thy pale orb to shroud\nBehind the gather'd blackness lost on high;\nAnd when thou dartest from the wind-rent cloud\nThy placid lightning o'er the awaken'd sky.",
    "translationTarget": "es",
    "wordCount": 58,
    "imageWidth": 1486,
    "imageHeight": 668,
    "lineGeometryAvailable": true,
    "wordGeometryAvailable": false,
    "geometryLevel": "LINE",
    "durationMs": 3154,
    "processedAt": "2026-08-01T16:51:13.248Z"
}
```

#### Result status

| Status      | Meaning                                                                                                |
| :---------- | :----------------------------------------------------------------------------------------------------- |
| `SUCCEEDED` | OCR completed. Requested translation also completed when text was available.                           |
| `PARTIAL`   | OCR completed, but an optional translation request failed. OCR text remains in the row.                |
| `FAILED`    | The image could not be loaded, decoded, or processed. The row contains `errorCode` and `errorMessage`. |

#### Field reference

| Field                       | Description                                                                                          |
| :--------------------------- | :---------------------------------------------------------------------------------------------------- |
| `inputId`                   | User-provided or deterministic correlation ID. PDF page rows append `-p<page>`.                      |
| `sourceType`                | `URL`, `BASE64`, `KEY_VALUE_STORE`, or `PDF`.                                                         |
| `sourceReference`           | URL or storage record reference. Base64 content is never copied into this field.                     |
| `sourcePdfUrl`              | For PDF rows: the source PDF URL this page came from.                                                 |
| `page`, `pageCount`         | For PDF rows: this page's 1-based number and the PDF's true total page count.                         |
| `status`                    | Per-input processing outcome.                                                                        |
| `language`                  | Language reported by Google, for the whole image.                                                    |
| `fullText`                  | Extracted lines joined with newline characters.                                                      |
| `translatedText`            | Real translated text when requested and completed.                                                   |
| `wordCount`                 | Whitespace-delimited word count calculated from `fullText`.                                          |
| `imageWidth`, `imageHeight` | Source image dimensions in pixels.                                                                    |
| `lineGeometryAvailable`     | Whether at least one genuine line box is present.                                                    |
| `wordGeometryAvailable`     | Whether at least one genuine word box is present. Only ever `true` when Output detail is `words`.     |
| `geometryLevel`             | `WORD` or `LINE`, whichever is the finest real geometry present in this row. Omitted for text-only rows. |
| `lines`                     | Extracted lines with normalized and pixel geometry when available.                                   |
| `paragraphs`                | Present when Output detail is `paragraphs` or `words`: each paragraph's writing direction, joined text, and (at `words`) every word's own box and rotation. |
| `regions`                   | Present at the same tiers: salient regions and objects Google's own response identifies, each with a real box when available. |
| `durationMs`                | Total processing time for that input.                                                                |
| `errorCode`, `errorMessage` | Real failure details for partial or failed rows.                                                     |

One real element from the sample row's `lines` array:

```json
{
    "text": "Mild Splendour of the various-vested Night!",
    "boundingBox": {
        "normalized": {
            "centerX": 0.44486331939697266,
            "centerY": 0.1067144051194191,
            "width": 0.8516666889190674,
            "height": 0.11873840540647507
        },
        "pixel": {
            "x": 28,
            "y": 32,
            "width": 1266,
            "height": 79
        }
    }
}
```

With `outputDetail: "words"` on the same image, the first paragraph's first word looks like this (also real, not estimated):

```json
{
    "writingDirection": "LTR",
    "text": "Mild Splendour of the various-vested Night! Mother of wildly-working visions! hail!",
    "words": [
        {
            "text": "Mild",
            "boundingBox": {
                "normalized": { "centerX": 0.067, "centerY": 0.1035, "width": 0.0958, "height": 0.1169 },
                "pixel": { "x": 28, "y": 30, "width": 142, "height": 78 },
                "rotation": 0.0049304598942399025
            }
        }
    ]
}
```

### 🛡️ Data integrity and limits

- The Actor does not fill missing values with invented labels, zero coordinates, or placeholder text.
- Word, line, paragraph, and region boxes are never estimated or interpolated. Every box, including rotation, comes directly from Google's own response.
- Input images are limited to 25 MB each.
- Translation is optional. If it fails after OCR succeeds, the row is marked `PARTIAL` and keeps the original text.
- OCR and translation depend on external services, so response time and availability can vary.
- Only process images that you are authorized to use.
- This is an independent tool. It is not affiliated with, endorsed by, or sponsored by Google. Google Lens is a trademark of Google LLC.

### 💳 Pricing

This Actor uses pay-per-event pricing, so you pay for the images it processes rather than for compute time. The exact per-image price, including volume discounts for higher Apify plans, is shown on the Pricing tab of this Actor's page. Each image that cannot be loaded or decoded still gets its own `FAILED` row with a clear error code, so nothing is silently dropped. Set a maximum cost per run in the run options if you want a hard spending cap on a large batch.

### ⭐ Enjoying Google Lens OCR?

<table style="display:table;width:100%;border-collapse:separate;border-spacing:0">
<tr>
<td style="padding:20px 24px 14px;background:#EAF1FB;border:1px solid #B8D4F4;border-left:5px solid #1A56C4;border-radius:10px 10px 0 0;color:#1C1917">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#172033">If this Actor made your image batch easier to audit, leave a rating.</span><br>
<span style="font-size:14px;color:#3F4B5F">A 5-star rating takes 10 seconds and helps other automation and AI teams find it. Your feedback also tells us which workflows to improve next.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#1A56C4;border:1px solid #1A56C4;border-left:5px solid #1A56C4;border-top:none;border-radius:0 0 10px 10px;text-align:center;color:#FFFFFF">
<a href="https://apify.com/getascraper/google-lens-ocr/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### ❓ FAQ

#### Does the Actor keep batch order?

Each row is saved as soon as its image finishes, so with more than one image at a time rows can arrive out of input order. Every row keeps its `inputId`, so sort or join on that.

#### Can I match results to my own database records?

Yes. Add a unique `inputId` to each item. The same value appears in its dataset row.

#### Does it return word bounding boxes?

Yes, when Output detail is set to `words`. Every word gets its own real box (from Google's own response, never estimated), with rotation. `full` and `paragraphs` stay at line-level geometry to keep the default payload small.

#### Can I upload an image instead of hosting it?

Yes. Use **Upload an image** in the input form to pick a screenshot, photo, or scan from your computer. The file is stored in your own Apify storage and read from there. Its result row uses the ID `upload-1`.

#### Can it OCR a PDF?

Yes. Give a PDF URL in `pdfUrl` (or many in `pdfUrls`). Every page becomes its own row with `page`, `pageCount`, and `sourcePdfUrl`. Scanned and digital PDFs both work. Use `maxPdfPages` to cap long documents.

#### What happens when one image fails?

The rest of the batch continues. The failed image receives its own `FAILED` row with an error code and message.

#### What happens when translation fails?

Valid OCR data is retained, and the row is marked `PARTIAL`.

#### Does it run as a Standby web server?

Yes. Find this Actor's Standby hostname on its Standby tab in Apify Console, then call `GET /ocr?imageUrl=...` for single-image requests with no cold start. Batch runs (`imageUrls`, `imagesBase64`, `imageKvsRecords`) are only available through a normal run, not through Standby.

### 🔗 Other actors

- [Google Lens Visual Search](https://apify.com/getascraper/google-lens-visual-search) ↗: Find visual matches, reverse-image search results, descriptions, and related links for an image.
- [Bulk Image Downloader](https://apify.com/getascraper/bulk-image-downloader) ↗: Download image batches with metadata, hashes, and Apify storage output.
- [arXiv RAG Extractor](https://apify.com/getascraper/arxiv-rag-extractor) ↗: Extract research papers as structured text for RAG pipelines.

# Changelog

This Actor's version history is a separate document: https://apify.com/getascraper/google-lens-ocr/changelog.md

# Actor input Schema

## `imageUrl` (type: `string`):

Public HTTP or HTTPS URL of the image to run OCR on. This is all most runs need. Use imageUrlInputId to attach your own correlation ID.

## `imageUrlInputId` (type: `string`):

Optional correlation ID for imageUrl. If omitted, the Actor assigns the deterministic ID single-1.

## `imageFile` (type: `string`):

Upload a screenshot, photo, or scan from your computer instead of hosting it online. Clear the Image URL field above if you only want the uploaded file processed. Its result row uses the ID upload-1.

## `imageUrls` (type: `array`):

Public image URLs. API callers can include userData.inputId on each URL object for correlation. Leave empty if you only need the single Image URL above.

## `imagesBase64` (type: `array`):

JSON array of objects with data and an optional inputId. data can be raw Base64 or an image data URI.

## `imageKvsRecords` (type: `array`):

JSON array of Apify key-value store records. Omit storeId to read from the run's default store. Records can contain binary image data, a Base64 string, or an object with a Base64 data field.

## `pdfUrl` (type: `string`):

Public HTTP or HTTPS URL of a PDF. Every page is rasterized and run through OCR, producing one result row per page with its page number. Use maxPdfPages to cap how many pages are processed.

## `pdfUrlInputId` (type: `string`):

Optional correlation ID for pdfUrl. If omitted, the Actor assigns the deterministic ID pdf-single-1. Each page row appends -pN (for example pdf-single-1-p1).

## `pdfUrls` (type: `array`):

Public PDF URLs. API callers can include userData.inputId on each URL object for correlation. Leave empty if you only need the single PDF URL above.

## `maxPdfPages` (type: `integer`):

Most pages to process per PDF. Pages beyond this are skipped; each row still reports the PDF's true total page count. Keeps runs bounded in time and cost, since each page is one OCR call.

## `outputDetail` (type: `string`):

Full (default) returns joined text and line boxes. Paragraphs also groups lines and reports writing direction (left-to-right, right-to-left, or top-to-bottom). Words adds every word's own real bounding box and rotation angle, roughly 9x more geometry data. Text only omits all geometry. Every box comes directly from Google; the Actor never estimates or interpolates one.

## `translateTo` (type: `string`):

Optional language code such as es, de, ja, or pt-BR. Translation failures keep the OCR data and mark the row PARTIAL.

## `maxConcurrency` (type: `integer`):

Number of images processed at once. Lower this for very large images or constrained memory.

## Actor input object example

```json
{
  "imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
  "imageUrlInputId": "",
  "imageFile": "",
  "imageUrls": [],
  "imagesBase64": [],
  "imageKvsRecords": [],
  "pdfUrl": "",
  "pdfUrlInputId": "",
  "pdfUrls": [],
  "maxPdfPages": 20,
  "outputDetail": "full",
  "translateTo": "",
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
    "imageUrlInputId": "",
    "imageUrls": [],
    "imagesBase64": [],
    "imageKvsRecords": [],
    "pdfUrl": "",
    "pdfUrlInputId": "",
    "pdfUrls": [],
    "maxPdfPages": 20,
    "outputDetail": "full",
    "translateTo": "",
    "maxConcurrency": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/google-lens-ocr").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
    "imageUrlInputId": "",
    "imageUrls": [],
    "imagesBase64": [],
    "imageKvsRecords": [],
    "pdfUrl": "",
    "pdfUrlInputId": "",
    "pdfUrls": [],
    "maxPdfPages": 20,
    "outputDetail": "full",
    "translateTo": "",
    "maxConcurrency": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/google-lens-ocr").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
  "imageUrlInputId": "",
  "imageUrls": [],
  "imagesBase64": [],
  "imageKvsRecords": [],
  "pdfUrl": "",
  "pdfUrlInputId": "",
  "pdfUrls": [],
  "maxPdfPages": 20,
  "outputDetail": "full",
  "translateTo": "",
  "maxConcurrency": 3
}' |
apify call getascraper/google-lens-ocr --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/google-lens-ocr"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eoVXILAQvzkbyNVrD/builds/oq8JACccdxBOYi89M/openapi.json
