A Singapore Government Agency Website

Data Extraction (Key Information Extraction)

The Document Key Information Extraction (KIE) API is AISAY’s most powerful capability. It extracts specific pieces of information from documents using a combination of OCR and Large Language Models (LLMs).

Use this API for all your extraction, analysis, and verification needs.

How It Works

  1. You send a document (PDF or image) along with a JSON schema describing what you want to extract
  2. AISAY runs OCR to reliably extract text from each page
  3. The LLM intelligently identifies which text is relevant to your query and returns structured results
  4. You receive a JSON response with the extracted data matching your schema

Unlike traditional OCR which relies on keyword matching, AISAY understands context. For example, if you search for “Groom’s Name” and a marriage certificate uses the label “Husband” instead, AISAY will still find the correct value.

Available Models

Feature Flagship Model Local Model
Invoke with data_classification='RSN' data_classification='CCE'
Hosting Overseas Singapore
Best for Text-heavy documents Image-heavy / visual documents
Processing speed Slightly slower Slightly faster
Max pages 150 pages 50 pages
Max file size 500 MB —
Supported formats PDF, JPG, TIFF, PNG, XLSX, DOCX, PPTX PDF, JPG, TIFF, PNG

Tip: Try both models on your use case and compare results. Flagship tends to be more accurate for text-heavy content, while Local performs better on image-heavy documents.

Schema Structure

The KIE API requires a vlm_prompt, a JSON schema that describes the fields you want to extract. The schema follows JSON Schema format.

Basic Example

Extract a name and NRIC from a document:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The full name of the individual as displayed in the document"
    },
    "nric": {
      "type": "string",
      "description": "The NRIC (National Registration Identity Card) number of the individual"
    }
  },
  "required": ["name", "nric"],
  "additionalProperties": false
}

Supported Field Types

Type Use When Example
string Extracting text, names, addresses, descriptions "type": "string"
number Extracting numeric values (no symbols or units) "type": "number"
boolean Checking a true/false condition "type": "boolean"
array Extracting a list of items (variable length) "type": "array"
object Grouping related fields together "type": "object"

Extracting Lists

When the number of items is unknown (e.g., line items on an invoice), use an array:

{
  "type": "object",
  "properties": {
    "vendor_name": {
      "type": "string",
      "description": "The name of the vendor"
    },
    "line_items": {
      "type": "array",
      "description": "All line items found on the invoice",
      "items": {
        "type": "object",
        "properties": {
          "item_name": {
            "type": "string",
            "description": "The name or description of the item"
          },
          "quantity": {
            "type": "number",
            "description": "The quantity ordered"
          },
          "unit_price": {
            "type": "string",
            "description": "The unit price including currency symbol, e.g. $50.00"
          }
        }
      }
    }
  },
  "required": ["vendor_name", "line_items"],
  "additionalProperties": false
}

When you need to maintain the association between related pieces of data, use objects within arrays. For example, extracting directors from an annual report:

{
  "type": "object",
  "properties": {
    "directors": {
      "type": "array",
      "description": "List of all board of directors found in the annual report",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The director's name, e.g. Mr Tan Ah Kow"
          },
          "designation": {
            "type": "string",
            "description": "The director's designation or title"
          },
          "years_of_experience": {
            "type": "number",
            "description": "Years of experience, e.g. 10"
          },
          "profile_summary": {
            "type": "string",
            "description": "A 100-word summary of the director's profile"
          }
        }
      }
    }
  },
  "required": ["directors"],
  "additionalProperties": false
}

Using KIE for Analysis

The KIE API is not limited to extracting facts — you can also use it to evaluate, assess, and generate commentary about documents.

Example: Analysing a sustainability report

{
  "type": "object",
  "properties": {
    "community_involvement": {
      "type": "string",
      "description": "How does the organisation engage local communities? Include donations, volunteering, programs, and partnerships. If none found, state 'Not found in report.'"
    },
    "areas_for_improvement": {
      "type": "string",
      "description": "Identify 3-6 gaps or weaknesses in the report. Look for: missing Scope 3, no targets, unclear methodology, weak metrics, vague claims."
    },
    "overall_rating": {
      "type": "string",
      "description": "Rate the report quality from 1-10. Include 3 strengths with evidence, 3 weaknesses, and 3 fixes to raise the score."
    }
  }
}

Using KIE for Verification

You can also use the KIE API for verification and anomaly detection tasks.

Example: Checking bank statements for suspicious activity

{
  "type": "object",
  "properties": {
    "missing_information": {
      "type": "string",
      "description": "Check if the statement is missing crucial information like the account holder's name or address, which could indicate the applicant is submitting someone else's statements."
    },
    "large_transactions": {
      "type": "string",
      "description": "Identify any significant deposits, large cash withdrawals, or large fund transfers that warrant further investigation."
    },
    "financial_difficulty": {
      "type": "string",
      "description": "Check for signs of financial difficulty such as repeatedly drawing down the account or dangerously low balances."
    },
    "overall_recommendation": {
      "type": "string",
      "description": "Based on all analysis, provide an overall conclusion and recommendation on whether to approve the application or seek a follow-up review."
    }
  }
}

API Request

import requests

import json
import urllib3

# Disable SSL warnings for dev/internal endpoints
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# 1. Configuration
API_KEY = "YOUR_API_KEY_HERE"
API_URL = "https://api.aisay.tech.gov.sg/v1/extract"
FILE_PATH = "path/to/your/document.pdf"

# 2. Define the Extraction Prompt Schema
# (Booleans are now capitalized for Python compatibility)
vlm_prompt = {
  "type": "object",
  "properties": {
    "account_holder_name": {
      "type": "string",
      "description": "Full name of the account holder as it appears on the bank statement. For example: John Tan Wee Kiat"
    },
    "statement_date": {
      "type": "string",
      "description": "The date when the bank statement was issued or covers. For example: 31/12/2023",
      "pattern": "^\\d{2}/\\d{2}/\\d{4}$"
    },
    "transactions": {
      "type": "array",
      "description": "A list of individual financial transactions recorded on the bank statement.",
      "items": {
        "type": "object",
        "properties": {
          "transaction_date": {
            "type": "string",
            "description": "Date the transaction occurred. For example: 15/12/2023",
            "pattern": "^\\d{2}/\\d{2}/\\d{4}$"
          },
          "transaction_description": {
            "type": "string",
            "description": "Brief description of the transaction, such as vendor name, type of payment, or transfer details. For example: Groceries at NTUC, Salary Deposit, ATM Withdrawal."
          },
          "transaction_amount": {
            "type": "number",
            "description": "The monetary value of the transaction. For example: -50.25 (for a debit), 2500.00 (for a credit)."
          }
        },
        "required": [
          "transaction_date",
          "transaction_description",
          "transaction_amount"
        ],
        "additionalProperties": False
      }
    }
  },
  "required": [
    "account_holder_name",
    "statement_date",
    "transactions"
  ],
  "additionalProperties": False
}

# 3. Prepare Payload
payload = {
    "model_type": "GENERAL",
    "data_classification": "RSN",
    "vlm_prompt": json.dumps(vlm_prompt),
    "source": "API"
}

# Note: Python `requests` handles multipart boundary automatically
files = [
    ('file', ('document.pdf', open(FILE_PATH, 'rb'), 'application/pdf'))
]

headers = {
    'Authorization': f'Bearer {API_KEY}'
}

# 4. Make Request
print("Sending request to AISAY...")
# verify=False is REQUIRED for dev endpoints using self-signed certs
response = requests.post(API_URL, headers=headers, files=files, data=payload, verify=False)

# 5. Handle Response
if response.status_code == 200:
    print("Success!")
    # The API will return JSON that matches your Schema structure
    print(json.dumps(response.json(), indent=2))
else:
    print(f"Error {response.status_code}: {response.text}")

Prompt Writing Tips

The description field in your schema is where you write your extraction instructions. Good descriptions lead to accurate results.

  • Be specific” describe what the value looks like and give examples
  • Handle edge cases” tell the AI what to return if the field is missing (e.g., “Return empty string if not found”)
  • Provide context” mention where in the document the information is typically located
  • Correct known errors” if the AI commonly misreads a value, explain the issue in your prompt

For detailed prompt-writing guidance, see the Prompt Writing Tips page.

Quick Start with Helper Tool

Visit https://tools.getaisay.com/API_Extraction_Helper to generate Python and cURL scripts for your extraction use case without writing code from scratch.

See Also

Chat with me!
Bot Launcher