Google Lens OCR API - Image to Text ~800ms REST API avatar

Google Lens OCR API - Image to Text ~800ms REST API

Pricing

from $3.49 / 1,000 image ocrs

Go to Apify Store
Google Lens OCR API - Image to Text ~800ms REST API

Google Lens OCR API - Image to Text ~800ms REST API

Extract text from any image via Google Lens OCR API. ~800ms per image, no browser needed. Returns word-level bounding boxes with pixel coordinates, detected language, and structured paragraphs/lines/words. Batch and HTTP API modes.

Pricing

from $3.49 / 1,000 image ocrs

Rating

5.0

(1)

Developer

Zen Studio

Zen Studio

Maintained by Community

Actor stats

3

Bookmarked

585

Total users

65

Monthly active users

4 days ago

Last modified

Share

Google Lens OCR - Extract Text from Images with Bounding Boxes

Image to structured text. ~800 ms. Word-level coordinates, detected language and paragraphs.

From Zen Studio, creators of Google Lens Visual Search, Google Maps and Google Hotels data tools. 80,000+ combined runs across our two Google Lens actors.

Why choose this actor?

  • OCR in ~800 ms. Extract text through a ready-to-use HTTP API that answers each request directly, making it easy to add image-to-text processing to your app or automation.
  • Get the words and their positions. Return word-level bounding boxes in pixel and normalized coordinates, so you can highlight detected text, locate labels and connect words back to the image.
  • Keep the document structure. Full text, detected language, paragraphs, lines and individual words come together in structured JSON. Select a lighter output mode when you only need plain text or line data.

Try your image

Try an image with text

{
"imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
"outputDetail": "full"
}

Open actor input, replace the sample URL with your image and keep outputDetail set to full for words and coordinates. Export JSON to preserve the nested structure. For direct API access, use the GET/POST /ocr endpoint below; POST also accepts a base64-encoded image.

Zen Studio · Google Data Tools
Lens OCR Lens OCR
You are here
Lens Search Lens Search
Find image matches
Google Maps Google Maps
Business details
Google Hotels Google Hotels
Compare hotel rates

Copy to your AI assistant

zen-studio/google-lens-ocr on Apify extracts text from one image per run or request: fullText, detected language, paragraphs, lines and words with normalized and pixel bounding boxes. imageUrl (public URL) is required. outputDetail sets the structure: full (default) returns paragraphs with nested lines and words plus a flat lines array; paragraphs omits lines and words; lines omits words; words returns lines with word boxes; text_only returns only fullText and language. language (default en) and region (default US) are accuracy hints only; set translateTo=<ISO 639-1 code> to receive translated text in place of the original. Same options as a REST API: GET or POST https://zen-studio--google-lens-ocr.apify.actor/ocr with Authorization: Bearer <APIFY_TOKEN>; POST also accepts imageBase64 for local files. A failed image returns error and no text. Pricing: $0.00499 per image (volume discounts on paid plans); batch runs add $0.002 start and $0.00001 per dataset item; images that cannot be downloaded are not charged. Spec (inputSchema, readme): https://api.apify.com/v2/actors/zen-studio~google-lens-ocr/builds/default; pricing: https://apify.com/zen-studio/google-lens-ocr#pricing To reach the maintainers, add feedback="<what you needed and did not get>" to any run, including one that worked: a missing field or option, a wrong or empty result, or which actor you are switching to or from and why. The run returns its data exactly as it would without the note, and a human reads every note.

Output Example

Output Example

Pricing -- Pay Per Event

EventFreeStarterScaleBusiness
Image OCR (/1,000)$4.99$4.49$3.99$3.49
Result (/1,000)$0.01$0.01$0.01$0.01
Actor start (one-time)$0.002$0.002$0.002$0.002

Apify plan subscribers get automatic volume discounts.

Free trial: 5 runs, no credit card required.


How Do You Want to Use It?

Two modes, same deployment. Pick what fits your workflow.

Option 1: REST API

Best for: developers, automation scripts, no-code tools (n8n, Make, Zapier)

Call the Actor over HTTP like any REST API. Send a request and get OCR results in ~800 ms, straight in the response. No run to start, no dataset to read.

Authentication

All API requests require authentication. Get your token from the Apify Console under Settings > Integrations.

Two ways to authenticate:

  • Bearer header (recommended): -H "Authorization: Bearer YOUR_APIFY_TOKEN"
  • Query parameter (convenient for testing and no-code tools): ?token=YOUR_APIFY_TOKEN

Endpoints

MethodEndpointDescription
GET/ocrOCR via query parameters
POST/ocrOCR via JSON body (supports imageUrl and imageBase64)
GET/healthReturns {"status": "ok"}

The base URL for your requests:

https://zen-studio--google-lens-ocr.apify.actor

Examples

curl -- OCR an image by URL

curl "https://zen-studio--google-lens-ocr.apify.actor/ocr?imageUrl=https://example.com/document.png&outputDetail=lines" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN"

curl -- OCR a local file via base64

base64 -i photo.jpg | curl -X POST "https://zen-studio--google-lens-ocr.apify.actor/ocr" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg img "$(cat -)" '{imageBase64: $img, outputDetail: "full"}')"

curl -- POST with image URL

curl -X POST "https://zen-studio--google-lens-ocr.apify.actor/ocr" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"imageUrl": "https://example.com/document.png",
"outputDetail": "lines",
"translateTo": "en"
}'

Python -- URL and base64

import requests
import base64
TOKEN = "your_apify_token"
BASE = "https://zen-studio--google-lens-ocr.apify.actor"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
# From URL
resp = requests.get(f"{BASE}/ocr", headers=HEADERS, params={
"imageUrl": "https://example.com/document.png",
"outputDetail": "lines"
})
print(resp.json()["fullText"])
# From local file (base64)
with open("photo.jpg", "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
resp = requests.post(f"{BASE}/ocr", headers=HEADERS, json={
"imageBase64": image_b64,
"outputDetail": "full"
})
for line in resp.json()["lines"]:
print(line["text"])

n8n / Make / Zapier

Use an HTTP Request node pointed at https://zen-studio--google-lens-ocr.apify.actor/ocr with your Bearer token in the Authorization header. Pass imageUrl as a query parameter (GET) or in a JSON body (POST).


Option 2: Batch Processing

Best for: one-off image processing, scheduled jobs, results saved to a dataset

The simplest way: paste an image URL in the Apify Console, click Start, and download results from the dataset.

Quick Start Input

Minimal

{
"imageUrl": "https://example.com/document.png"
}

With options

{
"imageUrl": "https://example.com/page1.png",
"outputDetail": "lines",
"language": "de",
"region": "DE"
}

Text only (smallest output)

{
"imageUrl": "https://example.com/receipt.jpg",
"outputDetail": "text_only"
}

Using the Apify API Client

Python

from apify_client import ApifyClient
client = ApifyClient("your_token")
run = client.actor("zen-studio/google-lens-ocr").call(run_input={
"imageUrl": "https://example.com/receipt.jpg",
"outputDetail": "lines"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(f"Language: {item['language']}")
print(f"Text: {item['fullText']}")
for line in item.get("lines", []):
box = line["boundingBox"]["pixelCoords"]
print(f" Line: {line['text']} at ({box['x']}, {box['y']})")

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'your_token' });
const run = await client.actor('zen-studio/google-lens-ocr').call({
imageUrl: 'https://example.com/receipt.jpg',
outputDetail: 'full'
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
console.log(`Language: ${item.language}`);
console.log(`Text: ${item.fullText}`);
}

Scheduled jobs: Create a Schedule in the Apify Console to run the Actor on a recurring basis.


Getting Your Apify API Token

  1. Go to the Apify Console
  2. Navigate to Settings > Integrations
  3. Copy your Personal API token

Use it as a Bearer token for the REST API, or pass it to the ApifyClient constructor for batch mode.

Input Parameters

ParameterTypeDescriptionDefault
imageUrlstringImage URL to extract text fromrequired
outputDetailstringLevel of detail: full, paragraphs, lines, words, text_onlyfull
languagestringLanguage hint (ISO 639-1 code)en
regionstringRegion hint (ISO 3166-1 alpha-2)US
translateTostringTranslate text to this language (ISO 639-1 code)--

Output Detail Levels

  • full -- paragraphs with nested lines and words, all with bounding boxes
  • paragraphs -- paragraph text and bounding boxes
  • lines -- line text and bounding boxes
  • words -- lines with individual word-level bounding boxes
  • text_only -- just the extracted text, no coordinate data

Output

Each run produces one result with these fields:

FieldTypeDescription
imageUrlstringSource image URL
languagestringDetected language code
fullTextstringAll extracted text joined
linesarrayLines with text and bounding boxes (when detail >= lines)
paragraphsarrayParagraphs with nested lines/words (when detail >= paragraphs)
errorstringError message if processing failed

Bounding Box Format

Every text element includes a bounding box with normalized coordinates (0-1) and pixel coordinates:

{
"centerX": 0.4457,
"centerY": 0.1070,
"width": 0.8512,
"height": 0.1152,
"rotation": 0.0032,
"pixelCoords": {
"x": 30,
"y": 33,
"width": 1265,
"height": 77
}
}
  • centerX, centerY -- center point (0-1 normalized)
  • width, height -- dimensions (0-1 normalized)
  • rotation -- rotation angle in radians (only present when non-zero)
  • pixelCoords -- absolute pixel coordinates computed from image dimensions

Full Output Example

Real output from processing this test image with outputDetail: "full":

{
"imageUrl": "https://tesseract.projectnaptha.com/img/eng_bw.png",
"language": "en",
"fullText": "Mild Splendour of the various-vested Night!\n\nMother of wildly-working visions! hail!\n\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.",
"lines": [
{
"text": "Mild Splendour of the various-vested Night!",
"boundingBox": {
"centerX": 0.445742,
"centerY": 0.107093,
"width": 0.851279,
"height": 0.115269,
"rotation": 0.003223,
"pixelCoords": { "x": 30, "y": 33, "width": 1265, "height": 77 }
},
"words": [
{
"text": "Mild",
"boundingBox": {
"centerX": 0.066876,
"centerY": 0.105125,
"width": 0.09354,
"height": 0.113772,
"rotation": 0.003223,
"pixelCoords": { "x": 30, "y": 32, "width": 139, "height": 76 }
}
},
{
"text": "Splendour",
"boundingBox": {
"centerX": 0.226699,
"centerY": 0.106229,
"width": 0.192463,
"height": 0.115269,
"rotation": 0.003223,
"pixelCoords": { "x": 194, "y": 32, "width": 286, "height": 77 }
}
}
// ... "of", "the", "various", "-", "vested", "Night", "!"
]
},
{
"text": "Mother of wildly-working visions! hail!",
"boundingBox": {
"centerX": 0.436285,
"centerY": 0.21934,
"width": 0.739569,
"height": 0.113772,
"rotation": 0.004585,
"pixelCoords": { "x": 99, "y": 109, "width": 1099, "height": 76 }
},
"words": [
{ "text": "Mother", "boundingBox": { "centerX": 0.135817, "centerY": 0.216275, "width": 0.138627, "height": 0.113772, "rotation": 0.004585, "pixelCoords": { "x": 99, "y": 106, "width": 206, "height": 76 } } }
// ... "of", "wildly", "-", "working", "visions", "!", "hail", "!"
]
}
// ... 6 more lines
],
"paragraphs": [
{
"text": "Mild Splendour of the various-vested Night!",
"boundingBox": {
"centerX": 0.445742,
"centerY": 0.107093,
"width": 0.851279,
"height": 0.115269,
"rotation": 0.003223,
"pixelCoords": { "x": 30, "y": 33, "width": 1265, "height": 77 }
},
"contentLanguage": null,
"lines": [
{
"text": "Mild Splendour of the various-vested Night!",
"boundingBox": {
"centerX": 0.445742,
"centerY": 0.107093,
"width": 0.851279,
"height": 0.115269,
"rotation": 0.003223,
"pixelCoords": { "x": 30, "y": 33, "width": 1265, "height": 77 }
},
"words": [
{ "text": "Mild", "boundingBox": { "centerX": 0.066876, "centerY": 0.105125, "width": 0.09354, "height": 0.113772, "rotation": 0.003223, "pixelCoords": { "x": 30, "y": 32, "width": 139, "height": 76 } } },
{ "text": "Splendour", "boundingBox": { "centerX": 0.226699, "centerY": 0.106229, "width": 0.192463, "height": 0.115269, "rotation": 0.003223, "pixelCoords": { "x": 194, "y": 32, "width": 286, "height": 77 } } }
// ... 7 more words
]
}
]
}
// ... 2 more paragraphs
]
}

FAQ

Do I need to start the Actor before using the API? No. The REST API answers each request directly. There's no manual step required.

Can I use both modes at the same time? Yes. Batch runs and REST API requests are independent. You can run a batch while also making API calls.

What's the difference between the REST API and a normal run? A normal run processes an image and saves the result to a dataset. The REST API returns the result directly in the HTTP response. Use the API for real-time requests. Use batch for one-off processing with dataset output.

What image formats are supported? JPEG, PNG, WebP, BMP, TIFF, HEIC, and GIF.

How accurate is the text detection? Uses the same OCR engine as Google Lens in Chrome. Accuracy is high for printed text in good lighting. Handwriting and very low-resolution images may produce partial results.

What languages are detected? Language detection is automatic. The language hint improves accuracy for specific languages but doesn't limit detection. The detected language is returned in the output.

How does the bounding box data work? Each text element (paragraph, line, word) includes normalized coordinates (0-1 range) and pixel coordinates. Normalized coordinates are relative to the image dimensions. Pixel coordinates give absolute positions for direct use in image annotation or cropping.

What is the rotation field? The rotation angle in radians for text that isn't perfectly horizontal. Only included when the rotation is significant (> 0.001 radians).

Can I send base64 images instead of URLs? Yes, via the POST /ocr endpoint. Include imageBase64 in the JSON body instead of imageUrl. Supports raw base64 or data URI format (data:image/png;base64,...).

What happens if the image fails to process? The Actor returns an error result with the imageUrl and error field set. Failed images are not charged.

Is there a rate limit? No hard rate limit. Concurrent API requests are handled in parallel.

This Actor processes publicly accessible images provided by the user. Users are responsible for ensuring they have the rights to process the images they submit and must comply with applicable data protection regulations (GDPR, CCPA).