> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.finput.com.au/api/endpoints/matrix-calculator/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.finput.com.au/_mcp/server. # Price a deal and find where it can be approved POST https://api.finput.com.au/api/v1/matrix-calculator/ Content-Type: application/json Runs the calculator and the Approval Matrix over one payload and returns the join: each financier that can **both** price the deal and approve it, with the rate and repayment from the cheapest rate card that financier accepts. The request is the union of the two tools' fields, so anything either accepts is accepted here. Two differences from the standalone surfaces: - **`term` is required.** Matrix treats it as optional because a broker without a term in mind can still ask who would approve a deal. There is no repayment without a term, so the combined tool demands it. - **Commercial only.** `type` accepts `commercial`; consumer pricing carries its own entitlement and commission columns and is not folded in yet. `home_owner` and `asset_owner` are the same question under the two tools' names. Send either; sending both with different values is rejected rather than silently resolved. The rate bracket is the join key, so a financier appears only when it can do both. An approval whose brackets were all filtered out by pricing has no rate to show and is omitted — it still appears in the standalone Matrix, which is the tool for that question. This is why `destination_count` can exceed the length of `results`. Requires the `matrix.enabled` entitlement, and `surfaces.matrix_calculator` on `GET /api/v1/feature-flags` to be `available`. A run decrements **both** the calculator and Matrix daily allowances, because it consumes both engines. If one engine fails and the other succeeds, the response is a 200 with `degraded` naming the missing half and the surviving half returned unjoined. An empty `results` with `degraded: null` means no financier matched; `degraded` set means the check could not be completed. The two are deliberately distinguishable. Reference: https://docs.finput.com.au/api/endpoints/matrix-calculator ## Authentication - `Authorization` header (bearer token, required) — JWT access token obtained from `POST /api/v1/auth/login`, or a `finput_sk_...` API token ## Request ### Headers - `X-Finput-Client` (enum, optional) — Which client is asking, so every `message` in the response is worded for it. `ios` and `android` get sentences that state a fact and nothing more: no plan, no price, no link. Absent means `web`, which keeps its existing wording. An unrecognised value is treated like `ios` and `android`. - Allowed values: `web`, `ios`, `android` ### Body (application/json) This endpoint expects a MatrixCalculatorRequest. - `cost` (string, required) — Asset cost. Compared GST-inclusive against an approval's `min_asset_cost` / `max_asset_cost`. A negative cost is rejected. - `asset_value` (integer, required) — Asset ID from `GET /api/v1/assets/search`. - `term` (integer, required) — Months. Required here even though Matrix treats it as optional — there is no repayment without a term. - `advance_arrears` (enum, required) — Whether payments are made at the start or end of each period. `none` prices in arrears. - Allowed values: `none`, `advance`, `arrears` - `repayment_frequency` (enum, required) — `none` prices monthly. - Allowed values: `yearly`, `quarterly`, `monthly`, `weekly`, `daily`, `none` - `cost_gst` (boolean, optional, default: false) — Whether `cost` already includes GST. - `abn_age` (integer, optional, nullable) — ABN age (months). - `gst_age` (integer, optional, nullable) — GST registration age (months). - `asset_age` (integer, optional, nullable) — Asset age (months). Derived from `year_model` when that is sent instead. - `year_model` (integer, optional, nullable) — Build year, used to derive `asset_age`. - `borrower_age_youngest` (integer, optional, nullable) — Youngest borrower's age (years). Tested against the approval's minimum — every borrower has to sit inside the band. - `borrower_age_oldest` (integer, optional, nullable) — Oldest borrower's age (years), tested against the maximum. A single-borrower deal can send `borrower_age` instead and the API mirrors it into both ends. - `borrower_age` (integer, optional, nullable) — Shorthand for a single-borrower deal. - `file_age` (integer, optional, nullable) — Age of the borrower's **credit file**, in months — not the deal file. Months to match every other age criterion on the form (ABN age, GST age, asset age); it was days until the unit was unified. - `credit_score` (integer, optional, nullable) — The borrower's credit score. A different criterion from `file_age`: this is the score, that is how long the file has existed, and an approval can gate on either or both. - `industry` (string, optional, nullable) — ANZSIC division. See `GET /api/v1/approvals/options`. - `asset_state` (enum, optional) - Allowed values: `none`, `new`, `used`, `demo` - `transaction_type` (enum, optional) - Allowed values: `purchase`, `refinance`, `sale_hire_back`, `capital_raise` - `home_owner` (boolean, optional, nullable) - `private_sale` (boolean, optional, nullable) - `sale_hire_back` (boolean, optional, nullable) - `preferred_financier` (list of integer, optional) — Restrict results to these organisation (financier) IDs. - `type` (enum, optional, default: commercial) — Commercial only for now. A consumer value is rejected rather than silently priced as commercial. - Allowed values: `commercial` - `deposit` (float, optional, default: 0) - `deposit_gst` (boolean, optional, default: false) - `deposit_percentage` (boolean, optional, default: false) — Treat `deposit` as a percentage of cost rather than dollars. - `brokerage` (float, optional, default: 0) - `brokerage_gst` (boolean, optional, default: false) - `brokerage_percentage` (boolean, optional, default: false) - `origination_fee` (float, optional, default: 0) - `origination_fee_gst` (boolean, optional, default: false) - `balloon` (float, optional, default: 0) - `balloon_gst` (boolean, optional, default: false) - `balloon_percentage` (boolean, optional, default: false) — Treat `balloon` as a percentage. A percentage above 100 is rejected; a dollar balloon above 100 is ordinary. - `doc_fee_financed` (string, optional, nullable) - `asset_owner` (boolean, optional, nullable) — The calculator's name for `home_owner`. Send either; both with different values is rejected. - `asset_age_plus_term` (integer, optional, nullable) - `employment_status` (string, optional, nullable) - `citizenship_status` (string, optional, nullable) - `lvr` (float, optional, nullable) — Loan-to-value ratio as a percentage of asset value. Cards whose `max_lvr` is below this drop out. ## Response ### 200 Priced approval destinations - `results` (list of MatrixCalculatorRow, optional) - `priced_count` (integer, optional) — Rate cards that survived pricing for this deal. - `destination_count` (integer, optional) — Approvals that were not ruled out. Can exceed the length of `results`, because an approval with no priced rate bracket has no rate to show and is omitted from the join. - `degraded` (enum, optional) — Null on a healthy run. Set when one engine failed and the other succeeded, naming the missing half (`rates` for the rate engine, `approvals` for the approval checks) — so an empty `results` can be told apart from "we could not check". - Allowed values: `rates`, `approvals` - `priced` (list of MatrixCalculatorResponsePricedItems, optional) — Present only on a degraded run where the rate engine survived: the unjoined rate cards, so the broker still sees something useful. - `financiers` (list of MatrixFinancierGroup, optional) — Present only on a degraded run where the approvals lookup survived: the unjoined Matrix groups. ## Errors ### 400 Bad Request Error Invalid input — a missing `term`, a consumer `type`, a balloon over 100%, or contradictory `home_owner` / `asset_owner`. - `error` (string, optional) - `errors` (map from string to list of string, optional) ### 403 Forbidden Error Matrix is not on this account (`entitlement_required`) or the feature is off (`feature_disabled`). - `error` (enum, required) - Allowed values: `feature_disabled`, `entitlement_required` - `detail` (string, required) — The sentence this endpoint sent before `message` existed. The same as `message` for `ios` and `android`; kept for the web. - `message` (string, optional) — Sent with `entitlement_required`: why, worded for the client named in `X-Finput-Client`. - `entitlement` (string, optional) — Sent with `entitlement_required`. ### 429 Too Many Requests Error Either daily allowance is spent. `metric` names which one, so the caller knows which limit to act on. - `error` (enum, required) - Allowed values: `cap_hit` - `detail` (string, required) — The sentence this endpoint sent before `message` existed. The same as `message` for `ios` and `android`; kept for the web. - `message` (string, required) — What happened, worded for the client named in `X-Finput-Client`. Show this rather than composing a sentence from the other fields. - `limit` (integer, required) - `used` (integer, required) - `metric` (enum, optional) — Which allowance ran out. Sent by `/matrix-calculator/`, which spends both. - Allowed values: `calculator`, `matrix` ## Types ### MatrixCalculatorRow One financier that can both price and approve the deal, carrying the approval verdict beside the figures from the cheapest rate card that approval accepts. - `organisation_id` (integer, optional) - `organisation_name` (string, optional) - `approval_id` (integer, optional) - `approval_name` (string, optional) - `doc_level` (enum, optional) — Documentation burden. Results sort least-onerous first. - Allowed values: `low_doc`, `lite_doc`, `full_doc` - `status` (enum, optional) - Allowed values: `confirmed`, `possible` - `missing_fields` (list of string, optional) - `deposit_percentage` (float, optional, nullable) - `deposit_amount` (float, optional, nullable) - `deposit_required` (float, optional, nullable) - `max_term` (integer, optional, nullable) - `product_id` (integer, optional) - `product_name` (string, optional) - `rate_bracket_id` (integer, optional) — The cheapest bracket this approval accepts for this deal. - `rate_bracket_name` (string, optional) - `base_min` (string, optional) — Rates and repayments are strings — the pricing engine serialises them that way. Parse before comparing numerically. - `base_max` (string, optional) - `e_min` (string, optional) — Minimum effective rate. Results sort on this within a status. - `e_max` (string, optional) - `repayment_min` (string, optional) - `repayment_max` (string, optional) - `balloon` (float, optional) - `commission` (float, optional) - `masked` (boolean, optional) — True when the Free-tier paywall has nulled this row's figures. The cheapest three rows stay visible. - `priced_bracket_count` (integer, optional) — How many of this approval's brackets survived pricing — not how many it has configured. Distinguishes a financier that barely fits from one that is narrow. ### MatrixCalculatorResponsePricedItems ### MatrixFinancierGroup - `organisation_id` (integer, optional) - `organisation_name` (string, optional) - `approvals` (list of MatrixApprovalResult, optional) ### MatrixApprovalResult One approval that was not ruled out. Approvals whose criteria the deal violates are omitted entirely rather than returned as a rejection. - `approval_id` (integer, optional) - `approval_name` (string, optional) - `doc_level` (enum, optional) — Documentation burden. Results sort least-onerous first. - Allowed values: `low_doc`, `lite_doc`, `full_doc` - `status` (enum, optional) — `confirmed` — every criterion the approval checks was supplied and satisfied. `possible` — a checked criterion had no input, so it could still qualify once that answer is known. A blank input is never treated as a violation. - Allowed values: `confirmed`, `possible` - `missing_fields` (list of string, optional) — Request fields that would need answering to move this row from `possible` to `confirmed`. - `deposit_percentage` (float, optional, nullable) - `deposit_amount` (float, optional, nullable) - `deposit_required` (float, optional, nullable) — Deposit this deal needs, resolved from the two fields above. - `max_term` (integer, optional, nullable) — Longest term (months) this approval will write. Also bounds a supplied `term`, so an approval capped below the requested term is dropped rather than returned. - `rate_bracket_ids` (list of integer, optional) — Rate brackets linked to this approval. ## Examples **Request** ```json { "cost": "100000", "asset_value": 42, "term": 60, "advance_arrears": "arrears", "repayment_frequency": "monthly", "cost_gst": false, "abn_age": 36, "gst_age": 24, "credit_score": 720, "asset_state": "used", "home_owner": true, "deposit": 10000, "brokerage": 2000, "balloon": 30, "balloon_percentage": true } ``` **Response** ```json { "results": [ { "organisation_id": 1, "organisation_name": "Dynamoney", "approval_id": 1, "approval_name": "Low doc to $150k, property owner", "doc_level": "low_doc", "status": "confirmed", "missing_fields": [ "string" ], "deposit_percentage": 1.1, "deposit_amount": 1.1, "deposit_required": 1.1, "max_term": 1, "product_id": 1, "product_name": "Chattel mortgage", "rate_bracket_id": 1, "rate_bracket_name": "Tier 1", "base_min": "7.95", "base_max": "9.95", "e_min": "7.95", "e_max": "9.95", "repayment_min": "221.31", "repayment_max": "231.53", "balloon": 1.1, "commission": 1.1, "masked": true, "priced_bracket_count": 1 } ], "priced_count": 1, "destination_count": 1, "degraded": "rates", "priced": [ {} ], "financiers": [ { "organisation_id": 1, "organisation_name": "Dynamoney", "approvals": [ { "approval_id": 1, "approval_name": "Low doc to $150k, property owner", "doc_level": "low_doc", "status": "confirmed", "missing_fields": [ "credit_score" ], "deposit_percentage": 1.1, "deposit_amount": 1.1, "deposit_required": 1.1, "max_term": 1, "rate_bracket_ids": [ 1 ] } ] } ] } ``` **SDK Code** ```python Matrix Calculator_example import requests url = "https://api.finput.com.au/api/v1/matrix-calculator/" payload = { "cost": "100000", "asset_value": 42, "term": 60, "advance_arrears": "arrears", "repayment_frequency": "monthly", "cost_gst": False, "abn_age": 36, "gst_age": 24, "credit_score": 720, "asset_state": "used", "home_owner": True, "deposit": 10000, "brokerage": 2000, "balloon": 30, "balloon_percentage": True } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Matrix Calculator_example const url = 'https://api.finput.com.au/api/v1/matrix-calculator/'; const options = { method: 'POST', headers: {Authorization: 'Bearer ', 'Content-Type': 'application/json'}, body: '{"cost":"100000","asset_value":42,"term":60,"advance_arrears":"arrears","repayment_frequency":"monthly","cost_gst":false,"abn_age":36,"gst_age":24,"credit_score":720,"asset_state":"used","home_owner":true,"deposit":10000,"brokerage":2000,"balloon":30,"balloon_percentage":true}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Matrix Calculator_example package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.finput.com.au/api/v1/matrix-calculator/" payload := strings.NewReader("{\n \"cost\": \"100000\",\n \"asset_value\": 42,\n \"term\": 60,\n \"advance_arrears\": \"arrears\",\n \"repayment_frequency\": \"monthly\",\n \"cost_gst\": false,\n \"abn_age\": 36,\n \"gst_age\": 24,\n \"credit_score\": 720,\n \"asset_state\": \"used\",\n \"home_owner\": true,\n \"deposit\": 10000,\n \"brokerage\": 2000,\n \"balloon\": 30,\n \"balloon_percentage\": true\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Matrix Calculator_example require 'uri' require 'net/http' url = URI("https://api.finput.com.au/api/v1/matrix-calculator/") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"cost\": \"100000\",\n \"asset_value\": 42,\n \"term\": 60,\n \"advance_arrears\": \"arrears\",\n \"repayment_frequency\": \"monthly\",\n \"cost_gst\": false,\n \"abn_age\": 36,\n \"gst_age\": 24,\n \"credit_score\": 720,\n \"asset_state\": \"used\",\n \"home_owner\": true,\n \"deposit\": 10000,\n \"brokerage\": 2000,\n \"balloon\": 30,\n \"balloon_percentage\": true\n}" response = http.request(request) puts response.read_body ``` ```java Matrix Calculator_example import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.finput.com.au/api/v1/matrix-calculator/") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"cost\": \"100000\",\n \"asset_value\": 42,\n \"term\": 60,\n \"advance_arrears\": \"arrears\",\n \"repayment_frequency\": \"monthly\",\n \"cost_gst\": false,\n \"abn_age\": 36,\n \"gst_age\": 24,\n \"credit_score\": 720,\n \"asset_state\": \"used\",\n \"home_owner\": true,\n \"deposit\": 10000,\n \"brokerage\": 2000,\n \"balloon\": 30,\n \"balloon_percentage\": true\n}") .asString(); ``` ```php Matrix Calculator_example request('POST', 'https://api.finput.com.au/api/v1/matrix-calculator/', [ 'body' => '{ "cost": "100000", "asset_value": 42, "term": 60, "advance_arrears": "arrears", "repayment_frequency": "monthly", "cost_gst": false, "abn_age": 36, "gst_age": 24, "credit_score": 720, "asset_state": "used", "home_owner": true, "deposit": 10000, "brokerage": 2000, "balloon": 30, "balloon_percentage": true }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` ```csharp Matrix Calculator_example using RestSharp; var client = new RestClient("https://api.finput.com.au/api/v1/matrix-calculator/"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"cost\": \"100000\",\n \"asset_value\": 42,\n \"term\": 60,\n \"advance_arrears\": \"arrears\",\n \"repayment_frequency\": \"monthly\",\n \"cost_gst\": false,\n \"abn_age\": 36,\n \"gst_age\": 24,\n \"credit_score\": 720,\n \"asset_state\": \"used\",\n \"home_owner\": true,\n \"deposit\": 10000,\n \"brokerage\": 2000,\n \"balloon\": 30,\n \"balloon_percentage\": true\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Matrix Calculator_example import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = [ "cost": "100000", "asset_value": 42, "term": 60, "advance_arrears": "arrears", "repayment_frequency": "monthly", "cost_gst": false, "abn_age": 36, "gst_age": 24, "credit_score": 720, "asset_state": "used", "home_owner": true, "deposit": 10000, "brokerage": 2000, "balloon": 30, "balloon_percentage": true ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.finput.com.au/api/v1/matrix-calculator/")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```