Direct API for High-Accuracy C# National ID Extraction

Achieve 99.8%+ accuracy and sub-second latency for National ID to JSON conversion via a single API call.

Steve HarringtonUpdated 2026-01-16
Diagram showing a photo of a national ID card being sent to the StructOCR API and returning a structured JSON object with extracted fields like name and document number.
Figure 1: StructOCR converts raw National ID images into validated JSON data.

Why National ID OCR is Difficult

Open-source OCR tools like Tesseract fail on real-world ID documents due to inherent complexities. Laminate glare, shadows, and non-uniform lighting obscure key text fields. Images captured from mobile devices introduce unpredictable skew and rotation, breaking template-based RegEx patterns. Furthermore, parsing the Machine-Readable Zone (MRZ) requires not just extraction but also checksum validation against ICAO 9303 standards. Manually implementing and maintaining these rules, along with country-specific date formats, results in a brittle, high-maintenance system with unacceptable error rates for production KYC workflows.

Enterprise-Grade Extraction with StructOCR

StructOCR replaces fragile RegEx with pre-trained Deep Learning models specifically architected for identity documents. Our API pipeline includes automatic image pre-processing, performing affine transformations to correct skew (deskewing) and applying filters to remove camera noise (denoising). Unlike Tesseract, which returns a raw dump of text coordinates, StructOCR's models identify and extract semantic fields—such as 'surname' or 'date_of_expiry'—and deliver them in a standardized, validated JSON format. This eliminates post-processing logic and provides a reliable, single-step data extraction solution.

Production Use Cases

  • Digital Onboarding (KYC): Reduce drop-off rates by pre-filling user data from National IDs in < 2 seconds.
  • Fraud Prevention: Detect tampered fonts or mismatched MRZ checksums automatically.
  • Global Compliance: Handle National IDs from 200+ jurisdictions without custom rules.

Implementation: Raw C# (HttpClient)

The following C# code demonstrates a complete flow using `System.Net.Http`. It correctly handles the `x-api-key` authentication and deserializes the specific National ID fields (CNP, CPF, Address, etc.).

Prerequisite: .NET Core 3.1+ or .NET 5/6/7+

CODE EXAMPLE
// 💰 Save 30%+ vs competitors. Get 200 free requests instantly:
// 👉 https://structocr.com/register

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

public class NationalIdOcrExample
{
    // 🔑 Need a key? Get 200 free requests instantly (No Credit Card required):
    // 👉 https://structocr.com/register
    private const string ApiKey = "YOUR_API_KEY_HERE";
    private const string ApiEndpoint = "https://api.structocr.com/v1/national-id";

    private static readonly HttpClient client = new HttpClient();

    public static async Task Main(string[] args)
    {
        // Note: Supports JPG, PNG, WebP (Max 4.5MB)
        string imagePath = "id_card.jpg";

        if (!File.Exists(imagePath))
        {
            Console.WriteLine($"Error: File not found at {imagePath}");
            return;
        }

        try
        {
            // 1. Prepare Payload
            byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
            string base64Image = Convert.ToBase64String(imageBytes);
            var payload = new { img = base64Image };

            // 2. Setup Request
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Add("x-api-key", ApiKey); // Required Header

            // 3. Send POST Request
            Console.WriteLine($"Scanning ID card at {ApiEndpoint}...");
            HttpResponseMessage response = await client.PostAsJsonAsync(ApiEndpoint, payload);

            // 4. Handle Response
            string responseBody = await response.Content.ReadAsStringAsync();

            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine($"API Error ({response.StatusCode}): {responseBody}");
                return;
            }

            // 5. Deserialize JSON
            var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
            var result = JsonSerializer.Deserialize<ApiResponse>(responseBody, options);

            if (result?.Success == true && result.Data != null)
            {
                var data = result.Data;
                Console.WriteLine("✅ Extraction Successful!");
                Console.WriteLine($"Region:     {data.CountryCode} (Series: {data.CardSeries})");
                Console.WriteLine($"Name:       {data.GivenNames} {data.Surname}");
                Console.WriteLine($"ID Number:  {data.DocumentNumber}");
                Console.WriteLine($"Personal #: {data.PersonalNumber} (CNP/CPF/NIN)");
                Console.WriteLine($"DOB:        {data.DateOfBirth} (Sex: {data.Sex})");
                Console.WriteLine($"Address:    {data.Address}");
            }
            else
            {
                Console.WriteLine("Extraction Failed.");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Unexpected Error: {e.Message}");
        }
    }
}

// --- Data Models matching the Schema ---
public class ApiResponse
{
    public bool Success { get; set; }
    public IdData Data { get; set; }
}

public class IdData
{
    [JsonPropertyName("country_code")]
    public string CountryCode { get; set; }
    
    [JsonPropertyName("document_number")]
    public string DocumentNumber { get; set; }

    [JsonPropertyName("personal_number")]
    public string PersonalNumber { get; set; }

    [JsonPropertyName("card_series")]
    public string CardSeries { get; set; }

    public string Surname { get; set; }
    
    [JsonPropertyName("given_names")]
    public string GivenNames { get; set; }
    
    public string Sex { get; set; }
    
    [JsonPropertyName("date_of_birth")]
    public string DateOfBirth { get; set; }
    
    public string Address { get; set; }
}

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

  • Specialized Numbers: Extracts region-specific IDs like CNP (Romania), CPF (Brazil), and NIN (Nigeria).
  • Multi-line Addresses: Intelligently reconstructs full addresses from fragmented lines on ID cards.
  • 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": "national_id",
    "country_code": "ROU",
    "nationality": "ROMANA",
    "document_number": "123456",
    "card_series": "KS",
    "personal_number": "1920319123456",
    "surname": "POPESCU",
    "given_names": "ANDREI",
    "sex": "M",
    "date_of_birth": "1992-03-19",
    "place_of_birth": "Jud. CS Mun. Reșița",
    "address": "Jud. CS Orș. Bocșa Str. Nucilor Nr. 15",
    "date_of_issue": "2020-05-10",
    "date_of_expiry": "2030-05-10",
    "issuing_authority": "SPCLEP Bocșa"
  }
}

Frequently Asked Questions

How does StructOCR compare to AWS Textract or Google Vision?

Generic cloud OCR services like Textract or Vision provide raw text blocks and coordinates. They require you to build and maintain complex parsing logic to identify fields like 'Date of Birth'. StructOCR is a specialized API trained specifically for identity documents. It returns a structured JSON with pre-identified, validated fields, eliminating the need for any post-processing on your end.

Do you store the uploaded images?

No. We have a strict data privacy policy. Images are processed in-memory and are permanently deleted immediately after the OCR process completes. We do not store any customer PII.

How to handle blurry images?

Our API includes an internal image enhancement engine that automatically applies deblurring and sharpening filters to low-quality images before processing to maximize extraction accuracy.

More OCR Tutorials

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