Fast Arabic + English OCR for screenshots, documents and images (normalised and raw text, lines with confidence, RTL order), plus exact fields from Saudi ZATCA e-invoice QR codes (signature not checked). For receipts and Arabic-Indic digits use Arabic Receipt Reader.
0.2 revisions (unreleased, local build only), 23 Oct 2026
boi's answers of 23 Oct 2026 and hitler's review fixes.
Dense pages: the small loss per dense page (about −$0.0008) is accepted for v1. The decision is recorded in PRICING.md.
Charging:chargedEvents in each row is built only from events actually charged (ChargeResult.charged_count) by the new save_row helper. The extra exact-qr-fields event is charged first. The row is then pushed together with plain-text-ocr. If the cap is hit between the two, the row lists only the event that went through, and it is saved free if plain-text-ocr no longer fits.
New e2e cases cap-between-qr-charged and cap-between-text-charged cover this. They use the test-only env hook TEST_RESERVE_MAIN_EVENT_ONLY=1, which is never set on the platform; normal runs reserve both events up front.
Refactor: preprocessing moved to the new shared imageprep.py, and the text-direction helpers moved to textutil.py. ocr.py now holds only Tesseract and the digit splice, and re-exports the moved names. check_shared.py lists the real shared files.
Sample fallback in the status message: when the bundled sample stands in, the run's status message and OUTPUT.note say so, for example "Input image failed to download; returned built-in sample instead".
Cross-links now point to https://apify.com/saif-tools/arabic-receipt-reader.
exact-qr-fields ($0.01) is unchanged in this actor.
Pinned dependencies:requirements.txt pins every direct dependency to the tested version.
0.2 (unreleased, local build only), 22 Oct 2026
boi's decisions of 22 Oct 2026 (11:39 PM), plus hitler's review notes.
Split. Full-OCR / receipt mode moved to the new actor arabic-receipt-reader. This actor keeps:
text: Tesseract plain text;
qr: exact QR fields.
No EasyOCR or torch dependency. The Docker image only adds the Tesseract binary. The local venv is 326 MB with no torch.
Memory: 1024 MB minimum and default (max 4096).
Events:plain-text-ocr ($0.003) and exact-qr-fields ($0.01). The SDK's apify-default-dataset-item event stays unpriced.
Every image is downscaled to at most 4 MP before OCR, and OCR upscaling is capped at the same 4 MP. Each row has imageSize with:
original
processed
downscaledBy
maxProcessedMegapixels
Boxes and QR points stay in original-image pixels.
Renamed field:exactQrFields.signatureVerified is now signatureChecked (always false).
Bundled sample images (sample/) are used when the input has no images, or when the Store example URL can't be downloaded (e.g. a 403 from Wikimedia):
sample-arabic-text.png in text mode;
sample-zatca-qr.png in qr mode.
Sample rows carry sample: true plus sampleReason, and are free.
imageUrls is no longer required.
mode: "full" now ends with a clear message pointing to Arabic Receipt Reader. The Console and CLI already reject it through the input schema enum.
Removed inputs:confidenceThreshold and sumToleranceCents (they belonged to receipt mode).
Shared modules are copied into both actors, and test/check_shared.py checks the copies are identical:
ocr, qr, zatca, digits, textutil, pipeline_common and the digit model;
the tests make_fixtures and test_qr.
0.1 (unreleased, local build only)
Three modes: text (Tesseract), full (EasyOCR with the digit classifier) and qr.
Arabic-Indic and Persian digit second pass, RTL line order, QR masking, ZATCA TLV decoding, full-OCR receipt fields.
Pay-per-event charging with a worst-case budget reservation and a clean stop at the spending limit.
2026-10-23
Pinned every dependency to the exact versions tested locally so the first Apify build matches.
Added constraints.txt (full pip freeze of the tested venv) so transitive dependencies are locked too; the Dockerfile installs with -c constraints.txt.