Go Passport OCR via a Simple HTTP POST Request
Achieve 99.8%+ accuracy on ICAO 9303 MRZ parsing in under 1500ms.

Why Passport OCR is Difficult
Parsing passport Machine Readable Zones (MRZ) is non-trivial. Off-the-shelf OCR engines like Tesseract fail on real-world inputs due to variable lighting, glare from laminates, and shadows. Skew and rotation further degrade accuracy, requiring complex pre-processing. The ICAO 9303 standard defines a specific OCR-B font and a checksum validation algorithm for each line of the MRZ. Implementing and maintaining RegEx patterns to parse this strict format, correctly calculate check digits, and handle variations across issuing countries becomes a significant engineering overhead.
Enterprise-Grade Extraction with StructOCR
StructOCR replaces fragile, rule-based systems with a robust API powered by pre-trained deep learning models. Our pipeline handles the entire process: automatic image pre-processing, including deskewing, denoising, and glare removal, is applied before analysis. Unlike Tesseract which returns unstructured text blocks, our specialized models are trained specifically on millions of identity documents to locate and parse the MRZ, validate checksums, and return a standardized, predictable JSON object. This eliminates the need for manual parsing logic.
Production Use Cases
- Digital Onboarding (KYC): Reduce drop-off rates by pre-filling user data from Passports in < 2 seconds.
- Fraud Prevention: Detect tampered fonts or mismatched MRZ checksums automatically.
- Global Compliance: Handle Passports from 200+ jurisdictions without custom rules.
Implementation: Go (Golang)
The following Go code demonstrates a robust implementation using standard libraries. It handles file reading, Base64 encoding, and parses both MRZ and VIZ (Visual Inspection Zone) data into native Go structs.
Prerequisite: Go 1.16+
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
// 💰 Save 30%+ vs competitors. Get 200 free requests instantly:
// 👉 https://structocr.com/register
// Response Structs matching the API Schema
type ApiResponse struct {
Success bool `json:"success"`
Data PassportData `json:"data"`
Error string `json:"error,omitempty"`
}
type PassportData struct {
PassportNumber string `json:"passport_number"`
Surname string `json:"surname"`
GivenNames string `json:"given_names"`
Nationality string `json:"nationality"`
CountryCode string `json:"country_code"`
DateOfBirth string `json:"date_of_birth"`
Sex string `json:"sex"`
DateOfExpiry string `json:"date_of_expiry"`
// VIZ Fields (Visual Inspection Zone)
PlaceOfBirth string `json:"place_of_birth"`
PlaceOfIssue string `json:"place_of_issue"`
}
func main() {
apiURL := "https://api.structocr.com/v1/passport"
apiKey := "YOUR_API_KEY_HERE"
imagePath := "passport.jpg" // Supports JPG, PNG, WebP
// 1. Read Image
imageBytes, err := os.ReadFile(imagePath)
if err != nil {
fmt.Printf("Error reading file: %v\n", err)
return
}
// 2. Encode to Base64
base64Image := base64.StdEncoding.EncodeToString(imageBytes)
// 3. Prepare Payload
payload, _ := json.Marshal(map[string]string{"img": base64Image})
// 4. Create Request
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(payload))
if err != nil {
fmt.Printf("Request creation failed: %v\n", err)
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", apiKey) // Required Header
// 5. Execute Request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Network error: %v\n", err)
return
}
defer resp.Body.Close()
// 6. Parse Response
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
fmt.Printf("API Error (%d): %s\n", resp.StatusCode, string(body))
return
}
var result ApiResponse
if err := json.Unmarshal(body, &result); err != nil {
fmt.Printf("JSON Parse Error: %v\n", err)
return
}
if result.Success {
data := result.Data
fmt.Println("✅ Extraction Successful!")
fmt.Printf("Passport #: %s\n", data.PassportNumber)
fmt.Printf("Name: %s %s\n", data.GivenNames, data.Surname)
fmt.Printf("Nation: %s (%s)\n", data.Nationality, data.CountryCode)
// Visual Zone Data
fmt.Printf("Birth Place:%s\n", data.PlaceOfBirth)
fmt.Printf("Issued At: %s\n", data.PlaceOfIssue)
} else {
fmt.Printf("Extraction failed: %s\n", result.Error)
}
}Technical Specs
- •Latency: < 5s (Average)
- •Uptime: 98.5% SLA
- •Security: AES-256 Encryption & SOC2 Compliant
- •Input: JPG, PNG, WebP (Base64 Encoded)
- •Max File Size: 4.5MB
- •Output: JSON (Structured Data)
Key Features
- •Visual Extraction (VIZ): Parses non-MRZ data fields like Place of Birth and Issuing Authority.
- •Global Support: Optimized for 195+ countries, handling complex backgrounds and holograms.
- •Date Normalization: Returns all dates (Birth, Issue, Expiry) in a standardized YYYY-MM-DD format.
Sample JSON Output
StructOCR returns a normalized JSON object, regardless of the input image angle or quality.
{
"success": true,
"data": {
"type": "passport",
"country_code": "USA",
"nationality": "UNITED STATES",
"passport_number": "E12345678",
"surname": "DOE",
"given_names": "JOHN",
"sex": "M",
"date_of_birth": "1990-01-01",
"place_of_birth": "NEW YORK, USA",
"date_of_issue": "2020-01-01",
"date_of_expiry": "2030-01-01",
"place_of_issue": "PASSPORT AGENCY"
}
}Frequently Asked Questions
How does StructOCR compare to AWS Textract or Google Vision?
Generic OCR services like AWS Textract or Google Vision return raw, unstructured lines of text. Developers are still required to write and maintain complex parsers to identify and validate specific fields. StructOCR is a specialized model for identity documents. It goes beyond OCR to provide structured, validated data fields directly in a clean JSON format, saving significant development time.
Do you store the uploaded images?
No. We operate on a zero-retention policy. Images are processed in-memory and are permanently deleted immediately after the transaction is complete. We do not store or log any PII.
How do you handle blurry or low-quality images?
Our API includes an automatic image enhancement engine that runs before the OCR process. It applies deblurring and denoising filters to improve the quality of suboptimal images, significantly increasing the probability of a successful extraction.
More OCR Tutorials
Go Driver's License OCR API
High-accuracy Go Driver's License OCR API for developers. Get structured JSON output in under 1.5s. Eliminate manual entry and parse PDF417 barcodes.
Go Invoice OCR API
High-accuracy Go invoice OCR API. Automate AP by converting unstructured invoices to structured JSON output. Eliminate manual entry and Tesseract errors.
Go National ID OCR API
High-accuracy National ID data extraction for Go developers. Get structured JSON output via a simple API call, replacing unreliable open-source tools.
Go VIN (Vehicle Identification Number) OCR API
Tutorial: How to use the StructOCR Go Client to extract data from VIN (Vehicle Identification Number)s. Includes code samples and JSON schema.
Precise Data Extraction and Seamless
Integration with AI-powered OCR API.
Empower your solutions with automated data extraction by
integrating best-in class StructOCR via API seamlessly.
No credit card required • Full API access included