A Singapore Government Agency Website

API Specifications

Overview

AISAY provides three synchronous REST APIs. All APIs use multipart form data for file uploads and return JSON responses.

Base URL: https://api.aisay.tech.gov.sg

Authentication

All API calls require a Bearer token in the Authorization header:

Authorization: Bearer <your-api-key>

Request API keys at https://go.gov.sg/aisaykey.

Note: For staging/dev endpoints using self-signed certificates, you may need to disable SSL verification (verify=False in Python).


Document Key Information Extraction (KIE)

Extract specific information from documents using a JSON schema.

Endpoint

POST /v1/extract

Request (Multipart Form Data)

Parameter Type Required Description
file file Yes The document file (PDF, JPG, PNG, TIFF, XLSX, DOCX, PPTX)
model_type string Yes GENERAL
data_classification string Yes RSN (Flagship) or CCE (Local)
vlm_prompt string Yes JSON schema as a stringified JSON object
source string Yes API

Model Limits

Limit Flagship (RSN) Local (CCE)
Max pages 150 50
Max file size 500 MB โ€”
Supported formats PDF, JPG, TIFF, PNG, XLSX, DOCX, PPTX PDF, JPG, TIFF, PNG

Schema Format

The vlm_prompt must be a valid JSON schema (stringified with json.dumps()) with:

  • Root type "object" with a "properties" field
  • Each property must have "type" and "description"
  • Supported types: string, number, boolean, array, object
  • Arrays must include an "items" definition
  • Use "required" to list mandatory fields
  • Set "additionalProperties": false to prevent unexpected fields

Example: Simple Extraction

import requests
import json
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

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

vlm_prompt = {
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "The full name of the individual as displayed in the document"
        },
        "nric": {
            "type": "string",
            "description": "The NRIC number, e.g. S1234567A"
        }
    },
    "required": ["name", "nric"],
    "additionalProperties": False
}

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

files = [
    ('file', ('document.pdf', open(FILE_PATH, 'rb'), 'application/pdf'))
]

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

response = requests.post(API_URL, headers=headers, files=files, data=payload, verify=False)

if response.status_code == 200:
    print(json.dumps(response.json(), indent=2))
else:
    print(f"Error {response.status_code}: {response.text}")

Example: Extraction with Arrays (Nested Objects)

This example extracts both simple fields and a list of transactions from a bank statement:

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
}

# Send using the same payload/files/headers pattern as above
payload = {
    "model_type": "GENERAL",
    "data_classification": "RSN",
    "vlm_prompt": json.dumps(vlm_prompt),
    "source": "API"
}

Document Classification

Classify documents into pre-defined categories.

Endpoint

POST /v1/classify

Request (Multipart Form Data)

Parameter Type Required Description
file file Yes The document file
data_classification string Yes RSN (Flagship) or CCE (Local)
document_categories string Yes Array of category/description objects, stringified with json.dumps()

Model Limits

Limit Flagship (RSN) Local (CCE)
Max pages 150 50
Max file size 20 MB โ€”
Supported formats PDF, JPG, TIFF, PNG, XLSX, DOCX PDF, JPG, TIFF, PNG, XLSX, DOCX

Example

import requests
import json
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

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

document_categories = [
    {
        "category": "PASSPORT",
        "description": "Official government-issued identity document for international travel, typically containing a photograph, personal details like name, date of birth, nationality, signature, and an expiry date."
    },
    {
        "category": "BANK_STATEMENT",
        "description": "A periodic summary from a financial institution detailing all transactions (deposits, withdrawals, transfers) in a specific account over a defined period, showing opening and closing balances, and often the account holder's name and address."
    },
    {
        "category": "PAYSLIP",
        "description": "A document issued by an employer to an employee, detailing the employee's gross earnings, itemized deductions (e.g., CPF contributions, income tax), and net pay for a specific pay period."
    },
    {
        "category": "UNCLASSIFIED",
        "description": "Any document that does not fit into the defined categories above."
    }
]

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

files = {
    "file": open(FILE_PATH, "rb")
}

data = {
    "document_categories": json.dumps(document_categories),
    "data_classification": "RSN"
}

response = requests.post(API_URL, headers=headers, files=files, data=data, verify=False)

if response.status_code == 200:
    result = response.json()
    print(f"Document Type: {result['document_type']}")
    print(json.dumps(result, indent=2))
else:
    print(f"Error {response.status_code}: {response.text}")

Document OCR

Extract all visible text from a document in markdown format.

Endpoint

POST /v1/parse

Request (Multipart Form Data)

Parameter Type Required Description
file file Yes The document file (PDF, JPG, PNG, TIFF)
data_classification string Yes RSN only โ€” this endpoint does not accept CCE

Important: The OCR endpoint only supports the Flagship model (RSN). Local model (CCE) is not available for this endpoint.

Example

import requests
import json

API_KEY = "YOUR_API_KEY_HERE"
API_URL = "https://api.aisay.tech.gov.sg/v1/parse"

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

files = {
    "file": open("path/to/your/document.pdf", "rb"),
    "data_classification": "RSN"
}

response = requests.post(API_URL, headers=headers, files=files)

if response.status_code == 200:
    result = response.json()
    print(result["parsed_document"])
else:
    print(f"Error {response.status_code}: {response.text}")

See Also

Chat with me!
Bot Launcher