Documentation
How to extract information from Receipt using SoceTonAI Script OCRΒΆ
In this guide, Iβll show how to use SoceTonAI Script OCR 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: false
model: model1
fields:
- name: receipt_no
label: "Receipt No"
find:
type: text
keywords:
- keyword: "Receipt"
index: 0
next_keyword_position: [ 1, -1, 1, 10 ]
- keyword: "No"
next_keyword_position: [ 1, -1, 1, 3 ]
- keyword: ":"
position_of_value: [1, -1, 12, 35]
words: 5
debug: false
returns:
- keywords
- words
- position
- name: date
label: "Date"
find:
type: text
keywords:
- keyword: "Date"
index: 0
next_keyword_position: [ 1, -1, 1, 3 ]
- keyword: ":"
position_of_value: [1, -1, 12, 50]
words: 10
debug: false
returns:
- keywords
- words
- position
- name: cashier
label: "Cashier"
find:
type: text
keywords:
- keyword: "Cashier"
index: 0
next_keyword_position: [ 1, -1, 1, 3 ]
- keyword: ":"
position_of_value: [1, -1, 12, 50]
words: 10
debug: false
returns:
- keywords
- words
- position
- name: subtotal
label: "Subtotal"
find:
type: text
keywords:
- keyword: "Subtotal"
index: 0
position_of_value: [1, -1, 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: [1, -1, 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: [1, -1, 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.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": 0,
"line_idx": 0,
"word_idx": 0,
"value": "Receipt",
"confidence": 0.9938670992851256,
"x1": 0.1426900584795321,
"y1": 0.3132183908045977,
"x2": 0.271345029239766,
"y2": 0.3342911877394636
},
{
"page_idx": 0,
"block_idx": 0,
"line_idx": 0,
"word_idx": 1,
"value": "No",
"confidence": 0.9896353483200072,
"x1": 0.1426900584795321,
"y1": 0.3132183908045977,
"x2": 0.271345029239766,
"y2": 0.3342911877394636
},
{
"page_idx": 0,
"block_idx": 0,
"line_idx": 0,
"word_idx": 2,
"value": ":",
"confidence": 0.9766205549240112,
"x1": 0.1426900584795321,
"y1": 0.3132183908045977,
"x2": 0.271345029239766,
"y2": 0.3342911877394636
}
],
"words": [
{
"page_idx": 0,
"block_idx": 4,
"line_idx": 0,
"word_idx": 0,
"value": "R",
"confidence": 0.9548880457878112,
"x1": 0.712280701754386,
"y1": 0.3160919540229885,
"x2": 0.7274853801169591,
"y2": 0.3304597701149425
},
{
"page_idx": 0,
"block_idx": 4,
"line_idx": 0,
"word_idx": 1,
"value": "-",
"confidence": 0.9844475984573364,
"x1": 0.7274853801169591,
"y1": 0.3160919540229885,
"x2": 0.7368421052631579,
"y2": 0.3304597701149425
},
{
"page_idx": 0,
"block_idx": 4,
"line_idx": 0,
"word_idx": 2,
"value": "2025-4582",
"confidence": 0.9900320172309875,
"x1": 0.735672514619883,
"y1": 0.3160919540229885,
"x2": 0.8538011695906432,
"y2": 0.3304597701149425
}
],
"position": {
"top": 0.29214559386973177,
"left": 0.36324143692564737,
"bottom": 0.3553639846743295,
"right": 0.9146198830409356
}
},
"date": {
"value": "2025-02-01 14:32",
"keywords": [
{
"page_idx": 0,
"block_idx": 1,
"line_idx": 0,
"word_idx": 0,
"value": "Date",
"confidence": 0.98410964012146,
"x1": 0.143859649122807,
"y1": 0.35727969348659,
"x2": 0.2023391812865497,
"y2": 0.3706896551724138
},
{
"page_idx": 0,
"block_idx": 1,
"line_idx": 0,
"word_idx": 1,
"value": ":",
"confidence": 0.9805136919021606,
"x1": 0.143859649122807,
"y1": 0.35727969348659,
"x2": 0.2023391812865497,
"y2": 0.3706896551724138
}
],
"words": [
{
"page_idx": 0,
"block_idx": 5,
"line_idx": 0,
"word_idx": 0,
"value": "2025-02-01",
"confidence": 0.9902722239494324,
"x1": 0.6584795321637427,
"y1": 0.3563218390804598,
"x2": 0.7812865497076024,
"y2": 0.3706896551724138
},
{
"page_idx": 0,
"block_idx": 5,
"line_idx": 0,
"word_idx": 1,
"value": "14:32",
"confidence": 0.9875518083572388,
"x1": 0.7929824561403509,
"y1": 0.3563218390804598,
"x2": 0.8526315789473684,
"y2": 0.3706896551724138
}
],
"position": {
"top": 0.3438697318007662,
"left": 0.31929824561403514,
"bottom": 0.3840996168582376,
"right": 0.9333333333333337
}
},
"cashier": {
"value": "Alex",
"keywords": [
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 0,
"word_idx": 0,
"value": "Cashier",
"confidence": 0.9842921495437622,
"x1": 0.1426900584795321,
"y1": 0.3955938697318008,
"x2": 0.2339181286549707,
"y2": 0.4090038314176245
},
{
"page_idx": 0,
"block_idx": 2,
"line_idx": 0,
"word_idx": 1,
"value": ":",
"confidence": 0.9545170664787292,
"x1": 0.1426900584795321,
"y1": 0.3955938697318008,
"x2": 0.2339181286549707,
"y2": 0.4090038314176245
}
],
"words": [
{
"page_idx": 0,
"block_idx": 6,
"line_idx": 0,
"word_idx": 0,
"value": "Alex",
"confidence": 0.9904902577400208,
"x1": 0.8046783625730994,
"y1": 0.3955938697318008,
"x2": 0.8549707602339182,
"y2": 0.4099616858237548
}
],
"position": {
"top": 0.38218390804597707,
"left": 0.2990810359231411,
"bottom": 0.4224137931034482,
"right": 0.885547201336675
}
},
"subtotal": {
"value": "$ 10.13",
"keywords": [
{
"page_idx": 0,
"block_idx": 15,
"line_idx": 0,
"word_idx": 0,
"value": "Subtotal",
"confidence": 0.9876084923744202,
"x1": 0.1426900584795321,
"y1": 0.6724137931034483,
"x2": 0.2385964912280701,
"y2": 0.6867816091954023
}
],
"words": [
{
"page_idx": 0,
"block_idx": 20,
"line_idx": 0,
"word_idx": 0,
"value": "$",
"confidence": 0.9751895666122437,
"x1": 0.7789473684210526,
"y1": 0.671455938697318,
"x2": 0.7906432748538011,
"y2": 0.6867816091954023
},
{
"page_idx": 0,
"block_idx": 20,
"line_idx": 0,
"word_idx": 1,
"value": "10.13",
"confidence": 0.9821220636367798,
"x1": 0.7941520467836257,
"y1": 0.671455938697318,
"x2": 0.8526315789473684,
"y2": 0.6877394636015326
}
],
"position": {
"top": 0.6580459770114943,
"left": 0.2865497076023391,
"bottom": 0.7011494252873564,
"right": 0.8979532163742691
}
},
"total": {
"value": "$ 10.64",
"keywords": [
{
"page_idx": 0,
"block_idx": 17,
"line_idx": 0,
"word_idx": 0,
"value": "Total",
"confidence": 0.9859429597854614,
"x1": 0.1415204678362573,
"y1": 0.7519157088122606,
"x2": 0.2035087719298245,
"y2": 0.7662835249042146
}
],
"words": [
{
"page_idx": 0,
"block_idx": 22,
"line_idx": 0,
"word_idx": 0,
"value": "$",
"confidence": 0.977675437927246,
"x1": 0.7777777777777778,
"y1": 0.7519157088122606,
"x2": 0.7894736842105263,
"y2": 0.7662835249042146
},
{
"page_idx": 0,
"block_idx": 22,
"line_idx": 0,
"word_idx": 1,
"value": "10.64",
"confidence": 0.9856039881706238,
"x1": 0.7929824561403509,
"y1": 0.7519157088122606,
"x2": 0.8526315789473684,
"y2": 0.7662835249042146
}
],
"position": {
"top": 0.7375478927203065,
"left": 0.2902923976608186,
"bottom": 0.7806513409961686,
"right": 0.8853801169590637
}
},
"payment_method": {
"value": "Card",
"keywords": [
{
"page_idx": 0,
"block_idx": 18,
"line_idx": 0,
"word_idx": 0,
"value": "Payment",
"confidence": 0.9925779104232788,
"x1": 0.1426900584795321,
"y1": 0.7863984674329502,
"x2": 0.3380116959064327,
"y2": 0.8093869731800766
},
{
"page_idx": 0,
"block_idx": 18,
"line_idx": 0,
"word_idx": 1,
"value": "Method",
"confidence": 0.9918427467346193,
"x1": 0.1426900584795321,
"y1": 0.7863984674329502,
"x2": 0.3380116959064327,
"y2": 0.8093869731800766
}
],
"words": [
{
"page_idx": 0,
"block_idx": 23,
"line_idx": 0,
"word_idx": 0,
"value": "Card",
"confidence": 0.9823371767997742,
"x1": 0.8,
"y1": 0.7911877394636015,
"x2": 0.8526315789473684,
"y2": 0.8045977011494253
}
],
"position": {
"top": 0.7634099616858238,
"left": 0.4775271512113617,
"bottom": 0.832375478927203,
"right": 0.8960735171261487
}
}
}
}