Skip to content

Schema Overview

The Quickli Public API uses comprehensive, validated schemas for all requests and responses. All schemas are defined using Zod and automatically generate TypeScript types and OpenAPI documentation.

  • Scenario Schema - Complete mortgage scenario structure including households, income, securities, loans, liabilities, and expenses
  • Servicing Result Schema - Detailed servicing calculation results including borrowing capacity, validations, and rate breakdowns
  • Product Schema - Lender product information with rate tables and product features
  • Policy Schema - Lending policy documents with triggers and content

All API requests are validated against Zod schemas before processing. If validation fails, you’ll receive a 422 Validation Error with detailed information about what went wrong.

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"issues": [
{
"path": ["scenario", "households", 0, "postcode"],
"message": "Expected number, received string"
}
]
},
"timestamp": "2025-11-03T10:30:00.000Z"
}
}
  • Required fields: Must be provided in every request
  • Optional fields: Can be omitted; sensible defaults will be applied

Fields marked as optional in the schema will have TypeScript type T | undefined.

TypeDescriptionExample
stringText value"hello"
numberNumeric value (integer or float)123, 45.67
booleanTrue or falsetrue, false
arrayList of values[1, 2, 3]
objectNested structure{ "key": "value" }
enumOne of a fixed set of values"owner_occupied", "investment"
unionOne of multiple typesstring | number

MongoDB ObjectIds are represented as 24-character hexadecimal strings:

"507f1f77bcf86cd799439011"

Valid format: Exactly 24 characters, hexadecimal (0-9, a-f)

All dates and timestamps use ISO 8601 format:

"2025-11-03T10:30:00.000Z"

The API provides TypeScript types that match the Zod schemas:

import type {
SaveableScenario,
ServicingResult,
LenderProduct,
Policy
} from '@quickli/validation';
// Type-safe scenario creation
const scenario: SaveableScenario = {
households: [{
id: 'household-1',
status: 'single',
num_adults: 1,
num_dependants: 0,
postcode: 2000,
shared_with_households: []
}],
income: [],
securities: [],
home_loans: [],
liabilities: [],
living_expenses: [],
// ... other fields
};

For plain JavaScript, follow the schema structure:

const scenario = {
households: [{
id: 'household-1',
status: 'single',
num_adults: 1,
num_dependants: 0,
postcode: 2000,
shared_with_households: []
}],
income: [],
securities: [],
// ... other fields
};
from typing import TypedDict, List, Optional
class Household(TypedDict):
id: str
status: str # 'single' | 'couple' | ...
num_adults: int
num_dependants: int
postcode: int
shared_with_households: List[str]
class Scenario(TypedDict):
households: List[Household]
income: List[dict]
securities: List[dict]
# ... other fields

Many fields have sensible defaults that are applied when not provided:

  • Empty arrays for all list fields (households, income, securities, etc.)
  • Default configuration objects for additional_info
  • Standard calculation settings

This minimal scenario will have defaults applied:

{
"scenario": {}
}

Becomes:

{
"scenario": {
"households": [],
"income": [],
"securities": [],
"home_loans": [],
"liabilities": [],
"living_expenses": [],
"rental_income": [],
"self_employed_income": [],
"home_loan_security_links": [],
"additional_info": {
"useDependantAges": false
// ... other defaults
}
}
}

Many fields use enums to restrict values to a specific set. Here are the most common:

'single' | 'couple' | 'de_facto' | 'divorced' | 'separated' | 'widowed'
'purchasing' | 'refinancing' | 'owned'
'house' | 'unit' | 'townhouse' | 'apartment' | 'land' | 'rural' | 'commercial' | 'industrial'
'owner_occupied' | 'investment'
'owner_occupied' | 'investment'
'variable_package' | 'variable_basic' | 'fixed' | 'line_of_credit' | 'construction'
'existing' | 'proposed'
'credit_card' | 'personal_loan' | 'car_loan' | 'student_loan' | 'other_liability'
  • Positive numbers: Values like loan amounts must be > 0
  • Percentages: Values like LVR must be 0-100
  • Postal codes: Australian postal codes (1000-9999)
  • Email format: Must be valid email address
  • ObjectId format: Must be 24-character hex string
  • Array minimums: Some arrays require at least 1 item
{
households: z.array(HouseholdSchema).min(0), // 0 or more households
income: z.array(IncomeSchema).min(0), // 0 or more income sources
securities: z.array(SecuritySchema).min(0), // 0 or more properties
// ... more fields
}

The complete OpenAPI 3.0 schema is available at:

https://api.quickli.com/api/v1/openapi.json

You can use this to:

  • Generate client libraries in any language
  • Validate requests/responses in your tests
  • Import into API development tools (Postman, Insomnia, etc.)

Last updated: 2025-11-03