Extract text from an image
The OCR API reads the text sitting inside a photo, screenshot, or scanned snapshot and hands it back as plain, searchable text. It matters because an image full of words is otherwise a dead end for search, indexing, or any downstream logic that expects text, not pixels.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
Text trapped in pixels
A picture of a receipt, a screenshot of a chat, a photo of a whiteboard — all of them contain information a human can read at a glance but a database cannot query, a search bar cannot find, and a script cannot parse. Optical character recognition exists precisely to bridge that gap, and it's been a practical technology since flatbed scanners and early recognition engines made digitizing paper archives feasible decades ago; the ocr api applies that same principle to whatever image lands in your pipeline today.
What you send and what comes back
You submit an image — a photo taken on a phone, a screenshot, a scanned page saved as a picture — and the service analyzes it to detect and transcribe the text it contains, returning the recognized content as plain text you can store, search, or feed into another process. It handles the kind of variability real-world images bring: uneven lighting, a slight tilt, text set against a busy background, since production images are rarely as clean as a lab scan.
The asynchronous request cycle
A call to POST /ocr/image returns a task_id straight away instead of making you hold a connection open while recognition runs. Once the text has been extracted, you're notified through a signed webhook — the right fit for a pipeline processing many images automatically — or you can fetch the result from a signed link that stays valid for 24 hours, useful when a person just needs to grab one transcription.
Where OCR fits into a larger system
This slots naturally behind a document-upload feature, a receipt-scanning app, an inventory tool photographing product labels, or any workflow where users hand over images instead of typed data. Because the endpoint is async and stateless per request, it scales the same way whether it's processing one user's upload or a batch job running through thousands of images overnight, without needing a different integration for either case.
Cost, retries, and data handling
Pricing is $0.010 per request plus $0.0575 per image, published and predictable, with no token systems or invented units. Images that fail recognition are retried three times before returning a clear error, and a failed task is never billed — you only pay for text actually delivered. Access requires prepaid balance, with no free tier or trial, which keeps the endpoint fast and free of abuse; without balance, calls return 402. Uploaded images and extracted text are deleted after the retention window and never used for training.
What you can do with it
Receipt and expense capture
An expense-tracking app lets users photograph a receipt and extracts the merchant, date, and amount as text instead of storing an unsearchable picture.
Screenshot-to-text for support tickets
A support tool converts a customer's screenshot of an error message into searchable text so agents can find similar tickets later.
Product label and inventory logging
A warehouse app photographs product labels on a shelf and extracts model numbers and text into the inventory system without manual keying.
Digitizing photographed documents
A field team photographs printed forms on-site and the recognized text feeds directly into a database back at the office.
FAQ
How do I extract text from an image using an API?
Send the image to POST /ocr/image and you get a task_id back right away. The ocr api processes it asynchronously and delivers the recognized text by signed webhook or a signed link valid for 24 hours.
Is the OCR API free?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
What image formats are accepted?
Standard image formats such as JPEG and PNG are supported, covering photos taken on a phone, screenshots, and scanned pages saved as pictures.
Does it work on photos, not just clean scans?
Yes, the recognition is built to handle real-world conditions like uneven lighting, a slight tilt, or text against a busy background, not just perfectly flat scans.
Can I process many images at once?
Yes. Each call is an independent async request returning its own task_id, so a batch job can submit thousands of images and collect results as they complete.
What happens if the OCR fails on an image?
The system retries three times before returning a clear error, and a failed task is never charged, so you only pay for text that's actually delivered.
How does the OCR API compare to just reading the image manually?
It replaces manual transcription with an automated call that returns structured, searchable text in seconds rather than requiring someone to type it out by hand.
How long is the extracted text available for download?
The signed link stays valid for 24 hours, or you can receive the text immediately via signed webhook; after the retention window the image and text are deleted and never used for training.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/ocr/image \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/imagen.jpg"}'const res = await fetch("https://api.kit.forhosting.com/ocr/image", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/imagen.jpg"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/ocr/image",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/imagen.jpg"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/ocr/image", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/imagen.jpg"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/imagen.jpg"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/ocr/image", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"image": "https://ejemplo.com/imagen.jpg"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "ocr.image",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 10 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |