Documentation
How to extract information from Receipt using SoceTonAI Script OCR - Freemium ModelΒΆ
In this guide, Iβll show how to use SoceTonAI Script OCR - Freemium Model to automatically extract key information from a Receipt. We begin by collecting the API credentials from soceton.com, then create a YAML script that instructs the OCR engine to read the information we need (YAML is provided at the end of this document). Finally, we send a read request to api.soceton.com to retrieve the structured output.
YAML that I am using for this requestΒΆ
document_type: Receipt
description: "Extract key information from Receipt using OCR"
development: true
return_ocr_output: false
return_full_text: true
model: freemium
fields:
- name: receipt_no
label: "Receipt No"
find:
type: text
keywords:
- keyword: "Receipt"
index: 0
next_keyword_position: [ 1, -1, 1, 15 ]
- keyword: "No"
position_of_value: [0.5, -0.5, 12, 35]
words: 5
debug: false
returns:
- keywords
- words
- position
- name: date
label: "Date"
find:
type: text
keywords:
- keyword: "Date"
index: 0
position_of_value: [0.5, -0.5, 12, 65]
words: 10
debug: false
returns:
- keywords
- words
- position
- name: cashier
label: "Cashier"
find:
type: text
keywords:
- keyword: "Cashier"
index: 0
position_of_value: [0.5, -0.5, 12, 65]
words: 10
debug: false
returns:
- keywords
- words
- position
- name: subtotal
label: "Subtotal"
find:
type: text
keywords:
- keyword: "Subtotal"
index: 0
position_of_value: [0.5, -0.5, 12, 55]
words: 10
debug: false
returns:
- keywords
- words
- position
- name: total
label: "Total"
find:
type: text
keywords:
- keyword: "Total"
index: 0
position_of_value: [0.5, -0.5, 12, 55]
words: 10
debug: false
returns:
- keywords
- words
- position
- name: payment_method
label: "Payment Method"
find:
type: text
keywords:
- keyword: "Payment"
index: 0
next_keyword_position: [ 1, -1, 1, 10 ]
- keyword: "Method"
position_of_value: [0.5, -0.5, 12, 20]
words: 5
debug: false
returns:
- keywords
- words
- position
The imageΒΆ
InΒ [1]:
from PIL import Image
img = Image.open("dummies/resized-images/receipt-1_0.jpg")
img = img.convert("RGB")
img
Out[1]:
Sending the requestΒΆ
InΒ [2]:
import json
import requests
from config import SOCETONAI_API_SECRET, SOCETONAI_API_KEY
def generate_result(url, image_path, rules_path, headers):
data = {}
files = {
"doc": open(image_path, "rb"),
"rules": open(rules_path, "r", encoding="utf-8")
}
response = requests.post(url, data=data, headers=headers, files=files)
return response
result = generate_result(
"https://api.soceton.com/script-ocr/read",
"dummies/resized-images/receipt-1_0.jpg",
"dummies/ymls/receipt-1_0-freemium.yml", {
"X-API-KEY": SOCETONAI_API_KEY,
"X-API-SECRET": SOCETONAI_API_SECRET
})
result = result.json()
values = {}
for k in result["result"].keys():
try:
values[k] = result["result"][k]["value"]
except Exception as e:
print(k, ":", e)
print(json.dumps(values, indent=4))
{
"receipt_no": "R-2025-4582",
"date": "2025-02-01 14:32",
"cashier": "Alex",
"subtotal": "$10.13",
"total": "$10.64",
"payment_method": "Card"
}
Annotating the result on the image (Optional)ΒΆ
Keywords are in green, value positions are in blue, and value words are in red.
InΒ [3]:
import numpy as np
import cv2
w, h = img.size
img_copy = np.asarray(img).copy()
def annotate_value(key):
try:
thickness = 2
color = (0, 0, 255)
position = result["result"][key]["position"]
top, left, bottom, right = int(position["top"] * h), int(position["left"] * w), int(position["bottom"] * h), int(position["right"] * w)
cv2.rectangle(img_copy, (left, top), (right, bottom), color, thickness)
except Exception as e:
print(e)
try:
thickness = 2
color = (0, 255, 0)
for keyword in result["result"][key]["keywords"]:
y1, x1, y2, x2 = int(keyword["y1"] * h), int(keyword["x1"] * w), int(keyword["y2"] * h), int(keyword["x2"] * w)
cv2.rectangle(img_copy, (x1, y1), (x2, y2), color, thickness)
except Exception as e:
print(e)
try:
thickness = 2
color = (255, 0, 0)
for word in result["result"][key]["words"]:
y1, x1, y2, x2 = int(word["y1"] * h), int(word["x1"] * w), int(word["y2"] * h), int(word["x2"] * w)
cv2.rectangle(img_copy, (x1, y1), (x2, y2), color, thickness)
except Exception as e:
print(e)
for k in result["result"].keys():
annotate_value(k)
Image.fromarray(img_copy)
Out[3]:
Printing the valuesΒΆ
InΒ [4]:
print(json.dumps(result, indent=4))
{
"success": true,
"result": {
"receipt_no": {
"value": "R-2025-4582",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 2,
"value": "Receipt",
"confidence": 96.0,
"x1": 0.1450292397660818,
"y1": 0.3160919540229885,
"x2": 0.271345029239766,
"y2": 0.3352490421455938
},
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 3,
"value": "No:",
"confidence": 96.0,
"x1": 0.1450292397660818,
"y1": 0.3160919540229885,
"x2": 0.271345029239766,
"y2": 0.3352490421455938
}
],
"words": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 4,
"value": "R-2025-4582",
"confidence": 92.0,
"x1": 0.7146198830409357,
"y1": 0.3160919540229885,
"x2": 0.8526315789473684,
"y2": 0.3304597701149425
}
],
"position": {
"top": 0.30651340996168586,
"left": 0.36157059314954043,
"bottom": 0.34482758620689646,
"right": 0.902923976608187
}
},
"date": {
"value": "2025-02-01 14:32",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 2,
"value": "Date:",
"confidence": 96.0,
"x1": 0.1450292397660818,
"y1": 0.3524904214559387,
"x2": 0.2011695906432748,
"y2": 0.3793103448275862
}
],
"words": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 3,
"value": "2025-02-01",
"confidence": 95.0,
"x1": 0.6596491228070176,
"y1": 0.3563218390804598,
"x2": 0.7801169590643274,
"y2": 0.3706896551724138
},
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 4,
"value": "14:32",
"confidence": 96.0,
"x1": 0.7941520467836257,
"y1": 0.3563218390804598,
"x2": 0.8526315789473684,
"y2": 0.3706896551724138
}
],
"position": {
"top": 0.3390804597701149,
"left": 0.279766081871345,
"bottom": 0.39272030651340994,
"right": 0.9309941520467836
}
},
"cashier": {
"value": "Alex",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 2,
"value": "Cashier:",
"confidence": 96.0,
"x1": 0.143859649122807,
"y1": 0.3908045977011494,
"x2": 0.2327485380116959,
"y2": 0.4195402298850574
}
],
"words": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 1,
"word_idx": 3,
"value": "Alex",
"confidence": 96.0,
"x1": 0.8058479532163743,
"y1": 0.3946360153256705,
"x2": 0.8538011695906432,
"y2": 0.4099616858237548
}
],
"position": {
"top": 0.37643678160919536,
"left": 0.2771929824561403,
"bottom": 0.4339080459770114,
"right": 0.9549707602339182
}
},
"subtotal": {
"value": "$10.13",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 5,
"word_idx": 2,
"value": "Subtotal",
"confidence": 96.0,
"x1": 0.143859649122807,
"y1": 0.6676245210727969,
"x2": 0.2362573099415204,
"y2": 0.696360153256705
}
],
"words": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 5,
"word_idx": 3,
"value": "$10.13",
"confidence": 96.0,
"x1": 0.7789473684210526,
"y1": 0.671455938697318,
"x2": 0.8526315789473684,
"y2": 0.6877394636015326
}
],
"position": {
"top": 0.6532567049808429,
"left": 0.28245614035087707,
"bottom": 0.710727969348659,
"right": 0.871491228070175
}
},
"total": {
"value": "$10.64",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 7,
"word_idx": 2,
"value": "Total",
"confidence": 96.0,
"x1": 0.1426900584795321,
"y1": 0.7509578544061303,
"x2": 0.2023391812865497,
"y2": 0.7662835249042146
}
],
"words": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 7,
"word_idx": 3,
"value": "$10.64",
"confidence": 58.0,
"x1": 0.7777777777777778,
"y1": 0.7509578544061303,
"x2": 0.8538011695906432,
"y2": 0.7672413793103449
}
],
"position": {
"top": 0.7432950191570882,
"left": 0.28584795321637435,
"bottom": 0.7739463601532568,
"right": 0.8584795321637435
}
},
"payment_method": {
"value": "Card",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 8,
"word_idx": 2,
"value": "Payment",
"confidence": 96.0,
"x1": 0.1450292397660818,
"y1": 0.7902298850574713,
"x2": 0.3368421052631579,
"y2": 0.8103448275862069
},
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 8,
"word_idx": 3,
"value": "Method",
"confidence": 96.0,
"x1": 0.1450292397660818,
"y1": 0.7902298850574713,
"x2": 0.3368421052631579,
"y2": 0.8103448275862069
}
],
"words": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 8,
"word_idx": 4,
"value": "Card",
"confidence": 96.0,
"x1": 0.8011695906432749,
"y1": 0.7902298850574713,
"x2": 0.8526315789473684,
"y2": 0.8055555555555556
}
],
"position": {
"top": 0.7801724137931034,
"left": 0.4738512949039265,
"bottom": 0.8204022988505746,
"right": 0.8848788638262324
}
}
},
"full_text": ": Example Mart : Cityville, CA 90000 ] Phone: (555) 112-3344\n' 123 Market Street\n4 Receipt No: R-2025-4582 j Date: 2025-02-01 14:32 } Cashier: Alex Milk 1L $2.99\n: Bread Loaf $189 |\nEggs (12-pack) $3.49\nBananas (1.2kg) $1.76\nq Subtotal $10.13\nTax (5%) $0.51\n: Total $10.64 |\nj Payment Method Card i\nThank you for shopping!\nThis is a fictional sample receipt. 3"
}