Kicks off the full automated underwriting workflow for a property:
reading the submitted documents, pulling market and comparable
evidence, underwriting the deal, and calculating the financial
model.
At least one document is required, each tagged with the role it
plays. Documents are validated and accepted before the run starts;
rejections are 422 and are never billed.
A completed run delivers report.excel_url (the populated workbook)
and results (the whole report as structured data). The default
options.delivery=public_link also creates report.url (a public link
anyone can open) and, if notification_email is set, emails it there. Choose private
delivery to create no public link and send no email; end_user_ref is
then required. Use embed-sessions for a private iframe.
underwriting.completed is delivered to registered webhook endpoints.
Sandbox runs complete instantly and send no email.
The uploaded documents to underwrite from, each with the role it
plays. Required — a run reads the property's own documents, so
there is no address-only mode.
Everything that decides whether a run can start is checked here,
not thirty minutes in: the document exists and has a file, its
role is unambiguous, no role is claimed twice, and the file's
format is one that role can be read from. Rejections are 422
and are never billed.
Optional. With public_link delivery (the default), receives an email with the public report link when the run completes. Omit it to send no email; the link is still returned as report.url. Private delivery and sandbox runs send no email.
Your stable opaque identifier for the customer this underwriting
belongs to. Reuse it across that customer's underwritings; each
run receives its own underwriting ID. References are scoped to
your partner account and map to separate app organizations.
GET /v1/underwritings?end_user_ref= filters your runs by owner.
Use an internal ID rather than an email.
This is an ownership identifier, not an authentication credential.
Your API key authorizes partner-level access. Your backend must
authenticate its users and check ownership before returning a run
to them. The reference does not restrict access to a public
report.url share link.
Omit it only when underwriting on your own behalf. If your
account is configured to require it, omitting it returns 422
(end_user_ref_required).
Whole seconds since created_at. Present while the run is active, so a caller can tell a run that just started from one approaching the 4-hour ceiling without doing date math.
Recommended seconds to wait before polling again. Present while the run is active; mirrors the Retry-After header. Prefer this over a hard-coded interval.
Headline metrics as plain numbers, lifted out of results for
convenience: value_base_usd, cap_rate, normalized_noi_usd,
levered_irr, dscr, equity_multiple, total_units and so
on, plus readiness_status and disclosure_count.
A metric the run could not establish is absent, never null —
the reason it is missing is in results, beside the figure.
The whole report, in the same shape the public report page is
rendered from (broker-public-underwriting-delivery-v1).
Present on a completed run when fetched individually; omitted
from list responses and webhook payloads, which would otherwise
carry megabytes.
Every figure is a {state, value, reason} triple, because the
product distinguishes a known zero from something it could not
establish. state is one of known, zero, unavailable,
not_applicable; when it is not known or zero, value is
null and reason says why in a sentence you can show a user.
Collections carry {state, items, reason}, where state is
available, partial, confirmed_empty or unavailable —
"we found none" and "we could not look" are different answers.
Top level: schema_version, generated_at, property,
chapters, critical_assumptions, readiness, release.
The chapters follow the argument the report makes:
answer (what it is worth, and the cap rate and NOI behind
that), income (unit mix and rent comparables),
revenue (the trailing-twelve income statement and the
year-one revenue waterfall), cost (the expense statement and
the normalizations applied to it), value (sale comparables
and a cap-rate sensitivity grid), buyer (returns, financing
and the annual cash-flow table), risk (market watch), next
(talking points).
readiness.disclosures is the part to surface next to any
figure you quote: each names something the run had to assume or
could not establish, with copy written to be shown to an end
user. critical_assumptions.items ranks the assumptions the
valuation is most sensitive to, with the dollar and IRR impact
of moving each.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Cactus Partner API","colors":{"primary":"#0E7C5B","light":"#34D399","dark":"#0A5C44"},"navbar":{"primary":{"type":"button","label":"Need API keys?","href":"https://www.trycactus.com/api-access"}},"footer":{"socials":{"website":"https://trycactus.com"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"cactus-10e55128","hasAudioNarration":false,"actualSubdomain":"cactus-10e55128","customDomains":["docs.trycactus.com"],"gitSource":{"type":"github","owner":"trycactus","repo":"cactus-partner-api","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6aef868e69e61846fb384f36","clientVersion":"0.0.4111","searchFilterCounts":[{"language":"default","tag":"API Reference","count":34},{"language":"default","tag":"Underwritings","count":13},{"language":"default","tag":"Guides","count":10},{"language":"default","tag":"Getting started","count":6},{"language":"default","tag":"Documents","count":5},{"language":"default","tag":"Reference","count":4},{"language":"default","tag":"Extractions","count":4},{"language":"default","tag":"Webhook Endpoints","count":3},{"language":"default","tag":"Usage","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/underwritings/start-an-automated-underwriting-run","slug":"/api-reference/underwritings/start-an-automated-underwriting-run","pageMetadata":{"title":"Start an automated underwriting run","description":"Kicks off the full automated underwriting workflow for a property:\nreading the submitted documents, pulling market and comparable\nevidence, underwriting the deal, and calculating the financial\nmodel.\n\nAt least one document is required, each tagged with the role it\nplays. Documents are validated and accepted before the run starts;\nrejections are `422` and are never billed.\n\nA completed run delivers `report.excel_url` (the populated workbook)\nand `results` (the whole report as structured data). The default\noptions.delivery=public_link also creates `report.url` (a public link\nanyone can open) and, if notification_email is set, emails it there. Choose private\ndelivery to create no public link and send no email; end_user_ref is\nthen required. Use embed-sessions for a private iframe.\n`underwriting.completed` is delivered to registered webhook endpoints.\nSandbox runs complete instantly and send no email.\n","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwritings","href":"/api-reference/underwritings/start-an-automated-underwriting-run","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Kicks off the full automated underwriting workflow for a property:\\nreading the submitted documents, pulling market and comparable\\nevidence, underwriting the deal, and calculating the financial\\nmodel.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"At least one document is required, each tagged with the role it\\nplays. Documents are validated and accepted before the run starts;\\nrejections are \", _jsx(_components.code, {\n children: \"422\"\n }), \" and are never billed.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"A completed run delivers \", _jsx(_components.code, {\n children: \"report.excel_url\"\n }), \" (the populated workbook)\\nand \", _jsx(_components.code, {\n children: \"results\"\n }), \" (the whole report as structured data). The default\\noptions.delivery=public_link also creates \", _jsx(_components.code, {\n children: \"report.url\"\n }), \" (a public link\\nanyone can open) and, if notification_email is set, emails it there. Choose private\\ndelivery to create no public link and send no email; end_user_ref is\\nthen required. Use embed-sessions for a private iframe.\\n\", _jsx(_components.code, {\n children: \"underwriting.completed\"\n }), \" is delivered to registered webhook endpoints.\\nSandbox runs complete instantly and send no email.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Start an automated underwriting run","description":"Kicks off the full automated underwriting workflow for a property:\nreading the submitted documents, pulling market and comparable\nevidence, underwriting the deal, and calculating the financial\nmodel.\n\nAt least one document is required, each tagged with the role it\nplays. Documents are validated and accepted before the run starts;\nrejections are `422` and are never billed.\n\nA completed run delivers `report.excel_url` (the populated workbook)\nand `results` (the whole report as structured data). The default\noptions.delivery=public_link also creates `report.url` (a public link\nanyone can open) and, if notification_email is set, emails it there. Choose private\ndelivery to create no public link and send no email; end_user_ref is\nthen required. Use embed-sessions for a private iframe.\n`underwriting.completed` is delivered to registered webhook endpoints.\nSandbox runs complete instantly and send no email.\n","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwritings","href":"/api-reference/underwritings/start-an-automated-underwriting-run","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"createUnderwriting","tags":["Underwritings"],"summary":"Start an automated underwriting run","description":"Kicks off the full automated underwriting workflow for a property:\nreading the submitted documents, pulling market and comparable\nevidence, underwriting the deal, and calculating the financial\nmodel.\n\nAt least one document is required, each tagged with the role it\nplays. Documents are validated and accepted before the run starts;\nrejections are `422` and are never billed.\n\nA completed run delivers `report.excel_url` (the populated workbook)\nand `results` (the whole report as structured data). The default\noptions.delivery=public_link also creates `report.url` (a public link\nanyone can open) and, if notification_email is set, emails it there. Choose private\ndelivery to create no public link and send no email; end_user_ref is\nthen required. Use embed-sessions for a private iframe.\n`underwriting.completed` is delivered to registered webhook endpoints.\nSandbox runs complete instantly and send no email.\n","parameters":["19e7768c-4b88-4bff-8e6e-90c8493ac549"],"requestBody":"82ac1ea2-549a-4690-a943-311a6eee437a","responses":{"202":"67ae7945-98e7-4d83-a6d1-6b92d0fa1f7e","400":"f7510718-c357-4ec5-b249-78e4b6d1f621","401":"248148ca-7e7f-46ca-b25f-d51d5dfe6511","403":"42aa186a-638c-4fa8-95e2-c1f7316720df","422":"33c7e8bf-db6c-451d-9857-06b44dde9604","429":"a4f8bc94-154f-4cd9-949f-ceb103149019"},"method":"post","type":"path","servers":["1a16f6a0-bda6-4bf3-9c8b-84185a6fb93b"],"security":["2297ff2f-d9c9-4023-b4d6-2a7b14510000"],"path":"/v1/underwritings","baseUrlOptions":["https://api.trycactus.com"],"title":"Start an automated underwriting run","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"19e7768c-4b88-4bff-8e6e-90c8493ac549":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255,"isRequired":false,"description":"Unique key making the request safely retryable.","uniqueKey":"","typeLabel":"string"},"description":"Unique key making the request safely retryable."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["property","documents"],"properties":{"property":{"type":"object","required":["address","asset_class"],"properties":{"address":{"type":"object","required":["line1","city","state","postal_code"],"properties":{"line1":{"type":"string","isRequired":true,"uniqueKey":"property.address.line1","typeLabel":"string"},"city":{"type":"string","isRequired":true,"uniqueKey":"property.address.city","typeLabel":"string"},"state":{"type":"string","minLength":2,"maxLength":2,"isRequired":true,"uniqueKey":"property.address.state","typeLabel":"string"},"postal_code":{"type":"string","isRequired":true,"uniqueKey":"property.address.postal_code","typeLabel":"string"},"line2":{"type":"string","uniqueKey":"property.address.line2","typeLabel":"string"}},"isRequired":true,"uniqueKey":"property.address","typeLabel":"object"},"asset_class":{"type":"string","description":"Asset classes with an underwriting model behind them — a narrower set than extraction reads, because a class without a compiled model cannot be underwritten.","enum":["multifamily","self-storage","industrial-outdoor-storage","industrial","office","retail","hotel"],"isRequired":true,"uniqueKey":"property.asset_class","typeLabel":"enum\u003cstring>"}},"isRequired":true,"uniqueKey":"property","typeLabel":"object"},"documents":{"type":"array","minItems":1,"maxItems":5,"description":"The uploaded documents to underwrite from, each with the role it\nplays. Required — a run reads the property's own documents, so\nthere is no address-only mode.\n\nEverything that decides whether a run can start is checked here,\nnot thirty minutes in: the document exists and has a file, its\nrole is unambiguous, no role is claimed twice, and the file's\nformat is one that role can be read from. Rejections are `422`\nand are never billed.\n","items":{"type":"object","required":["document_id"],"properties":{"document_id":{"type":"string","example":"doc_01J9ZJXV","isRequired":true,"uniqueKey":"documents.items.[INDEX].document_id","typeLabel":"string"},"role":{"type":"string","description":"Omit to take the role implied by the document's\n`declared_type`: `rent_roll` → `rent_roll`, `t12` →\n`t12`, `offering_memorandum` →\n`offering_memorandum`, `other_standard` /\n`other_complex` → `supporting`. Name it when the\nimplied role is wrong — a seller's model has no\nimplied type and must be named `financial_model`.\n","enum":["rent_roll","t12","financial_model","offering_memorandum","supporting"],"uniqueKey":"documents.items.[INDEX].role","typeLabel":"enum\u003cstring>"}},"uniqueKey":"documents.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"documents","typeLabel":"object[]"},"notification_email":{"type":"string","format":"email","description":"Optional. With public_link delivery (the default), receives an email with the public report link when the run completes. Omit it to send no email; the link is still returned as report.url. Private delivery and sandbox runs send no email.","uniqueKey":"notification_email","typeLabel":"string\u003cemail>"},"end_user_ref":{"type":"string","minLength":1,"maxLength":255,"description":"Your stable opaque identifier for the customer this underwriting\nbelongs to. Reuse it across that customer's underwritings; each\nrun receives its own underwriting ID. References are scoped to\nyour partner account and map to separate app organizations.\n`GET /v1/underwritings?end_user_ref=` filters your runs by owner.\nUse an internal ID rather than an email.\n\nThis is an ownership identifier, not an authentication credential.\nYour API key authorizes partner-level access. Your backend must\nauthenticate its users and check ownership before returning a run\nto them. The reference does not restrict access to a public\n`report.url` share link.\n\nOmit it only when underwriting on your own behalf. If your\naccount is configured to require it, omitting it returns `422`\n(`end_user_ref_required`).\n","uniqueKey":"end_user_ref","typeLabel":"string"},"options":{"type":"object","additionalProperties":false,"properties":{"delivery":{"type":"string","enum":["public_link","private"],"default":"public_link","description":"Private delivery creates no public share link and sends no completion email. Use the authenticated API or an embed session to view results. Private delivery requires end_user_ref.","uniqueKey":"options.delivery","typeLabel":"enum\u003cstring>"},"perspective":{"type":"string","enum":["broker"],"default":"broker","description":"Who the underwriting is written for. Only broker is available, matching the app. Investor is not yet supported.","uniqueKey":"options.perspective","typeLabel":"enum\u003cstring>"},"mode":{"type":"string","enum":["light","medium","heavy"],"default":"medium","description":"How much effort the analyst spends. `heavy` is slower and more expensive to run; `light` is quicker and shallower.","uniqueKey":"options.mode","typeLabel":"enum\u003cstring>"},"notes":{"type":"string","maxLength":10000,"default":"","description":"Optional deal context for the Analyst, evaluated alongside the selected documents. Leading and trailing whitespace is trimmed. Matches the app's Notes field.","uniqueKey":"options.notes","typeLabel":"string"}},"uniqueKey":"options","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"property":{"address":{"line1":"\u003cstring>","city":"\u003cstring>","state":"\u003cstring>","postal_code":"\u003cstring>","line2":"\u003cstring>"}},"documents":[{"document_id":"doc_01J9ZJXV"}],"notification_email":"jsmith@example.com","end_user_ref":"\u003cstring>","options":{"delivery":"public_link","perspective":"broker","mode":"medium","notes":""}}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"67ae7945-98e7-4d83-a6d1-6b92d0fa1f7e":{"description":"Run queued.","headers":{"Request-Id":{"description":"Unique request identifier; quote in support requests.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["id","object","status","created_at","sandbox"],"properties":{"id":{"type":"string","example":"uw_01J9ZK3M","isRequired":true,"uniqueKey":"id","typeLabel":"string"},"object":{"type":"string","const":"underwriting","isRequired":true,"uniqueKey":"object","typeLabel":"string"},"status":{"type":"string","description":"`queued` → `ingesting` (reading the documents and the market) →\n`underwriting` (analysis) → `calculating` (the financial model) →\n`completed`. `progress.stage` carries the finer-grained pipeline\nstep behind each.\n","enum":["queued","ingesting","underwriting","calculating","completed","failed"],"isRequired":true,"uniqueKey":"status","typeLabel":"enum\u003cstring>"},"sandbox":{"type":"boolean","isRequired":true,"uniqueKey":"sandbox","typeLabel":"boolean"},"created_at":{"type":"string","format":"date-time","isRequired":true,"uniqueKey":"created_at","typeLabel":"string\u003cdate-time>"},"progress":{"type":"object","properties":{"phase":{"type":"string","uniqueKey":"progress.phase","typeLabel":"string"},"stage":{"type":"string","description":"The pipeline step in progress — `document_pack`, `market_pack`, `subject_seed`, `financial_mapping`, `underwriting_analysis`, `excel_calculation`, `agent_review`, `recalculation`, `finalizing`, `complete`. Informational only — new steps appear here without a `status` change, so branch on `status`, not on this.","uniqueKey":"progress.stage","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"progress.detail","typeLabel":"string"}},"uniqueKey":"progress","typeLabel":"object"},"property":{"type":"object","description":"Echo of the submitted property.","uniqueKey":"property","typeLabel":"object"},"end_user_ref":{"type":"string","description":"Echo of the submitted end-user identifier, when one was supplied.","uniqueKey":"end_user_ref","typeLabel":"string"},"version":{"type":"integer","description":"Report version. 1 for a first run; a confirmed change creates a new underwriting with the next number.","uniqueKey":"version","typeLabel":"integer"},"previous_underwriting_id":{"type":"string","description":"The version this one changed (absent on version 1).","uniqueKey":"previous_underwriting_id","typeLabel":"string"},"documents":{"type":"array","description":"Echo of the submitted selection, with each role settled.","items":{"type":"object","properties":{"document_id":{"type":"string","uniqueKey":"documents.items.[INDEX].document_id","typeLabel":"string"},"role":{"type":"string","description":"What a document is *for* in the run. At most one document per role.\n\n| Role | Accepted formats |\n|---|---|\n| `rent_roll` | PDF, XLS, XLSX, XLSM |\n| `t12` | PDF, XLS, XLSX, XLSM |\n| `financial_model` | XLS, XLSX, XLSM |\n| `offering_memorandum` | PDF |\n| `supporting` | PDF, XLS, XLSX, XLSM |\n","enum":["rent_roll","t12","financial_model","offering_memorandum","supporting"],"uniqueKey":"documents.items.[INDEX].role","typeLabel":"enum\u003cstring>"}},"uniqueKey":"documents.items.[INDEX]","typeLabel":"object"},"uniqueKey":"documents","typeLabel":"object[]"},"options":{"type":"object","description":"Echo of the submitted options, with defaults applied.","uniqueKey":"options","typeLabel":"object"},"billed_total_usd":{"type":"string","uniqueKey":"billed_total_usd","typeLabel":"string"},"completed_at":{"type":"string","format":"date-time","uniqueKey":"completed_at","typeLabel":"string\u003cdate-time>"},"elapsed_seconds":{"type":"integer","description":"Whole seconds since `created_at`. Present while the run is active, so a caller can tell a run that just started from one approaching the 4-hour ceiling without doing date math.","example":640,"uniqueKey":"elapsed_seconds","typeLabel":"integer"},"poll_after_seconds":{"type":"integer","description":"Recommended seconds to wait before polling again. Present while the run is active; mirrors the `Retry-After` header. Prefer this over a hard-coded interval.","example":30,"uniqueKey":"poll_after_seconds","typeLabel":"integer"},"report":{"type":"object","description":"Present when completed. Private delivery omits url.","properties":{"url":{"type":"string","format":"uri","description":"Present only for public_link delivery. Public link to the underwriting report. Anyone holding it\ncan open it, with no login. It is **live**: it shows the\nreport as it stands whenever someone opens it, so a later\ncorrection reaches everyone already sent the link.\n\nIt does not expire. Access ends by revoking the link, which\nis why there is no expiry to read here.\n","uniqueKey":"report.url","typeLabel":"string\u003curi>"},"excel_url":{"type":"string","description":"Path to `GET /v1/underwritings/{id}/model`, which returns a short-lived download URL for the populated Excel model — the workbook behind the report, in a form an analyst can keep working in.","example":"/v1/underwritings/uw_01J9ZK3M/model","uniqueKey":"report.excel_url","typeLabel":"string"}},"uniqueKey":"report","typeLabel":"object"},"summary":{"type":"object","description":"Headline metrics as plain numbers, lifted out of `results` for\nconvenience: `value_base_usd`, `cap_rate`, `normalized_noi_usd`,\n`levered_irr`, `dscr`, `equity_multiple`, `total_units` and so\non, plus `readiness_status` and `disclosure_count`.\n\nA metric the run could not establish is **absent**, never null —\nthe reason it is missing is in `results`, beside the figure.\n","additionalProperties":true,"uniqueKey":"summary","typeLabel":"object"},"results":{"type":"object","description":"The whole report, in the same shape the public report page is\nrendered from (`broker-public-underwriting-delivery-v1`).\nPresent on a completed run when fetched individually; omitted\nfrom list responses and webhook payloads, which would otherwise\ncarry megabytes.\n\nEvery figure is a `{state, value, reason}` triple, because the\nproduct distinguishes a known zero from something it could not\nestablish. `state` is one of `known`, `zero`, `unavailable`,\n`not_applicable`; when it is not `known` or `zero`, `value` is\nnull and `reason` says why in a sentence you can show a user.\nCollections carry `{state, items, reason}`, where `state` is\n`available`, `partial`, `confirmed_empty` or `unavailable` —\n\"we found none\" and \"we could not look\" are different answers.\n\nTop level: `schema_version`, `generated_at`, `property`,\n`chapters`, `critical_assumptions`, `readiness`, `release`.\n\nThe chapters follow the argument the report makes:\n`answer` (what it is worth, and the cap rate and NOI behind\nthat), `income` (unit mix and rent comparables),\n`revenue` (the trailing-twelve income statement and the\nyear-one revenue waterfall), `cost` (the expense statement and\nthe normalizations applied to it), `value` (sale comparables\nand a cap-rate sensitivity grid), `buyer` (returns, financing\nand the annual cash-flow table), `risk` (market watch), `next`\n(talking points).\n\n`readiness.disclosures` is the part to surface next to any\nfigure you quote: each names something the run had to assume or\ncould not establish, with copy written to be shown to an end\nuser. `critical_assumptions.items` ranks the assumptions the\nvaluation is most sensitive to, with the dollar and IRR impact\nof moving each.\n","additionalProperties":true,"uniqueKey":"results","typeLabel":"object"},"error":{"type":"object","properties":{"code":{"type":"string","uniqueKey":"error.code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"error.message","typeLabel":"string"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"id":"uw_01J9ZK3M","object":"underwriting","status":"queued","sandbox":true,"created_at":"2023-11-07T05:31:56Z","progress":{"phase":"\u003cstring>","stage":"\u003cstring>","detail":"\u003cstring>"},"property":{},"end_user_ref":"\u003cstring>","version":123,"previous_underwriting_id":"\u003cstring>","documents":[{"document_id":"\u003cstring>","role":"rent_roll"}],"options":{},"billed_total_usd":"\u003cstring>","completed_at":"2023-11-07T05:31:56Z","elapsed_seconds":640,"poll_after_seconds":30,"report":{"url":"\u003cstring>","excel_url":"/v1/underwritings/uw_01J9ZK3M/model"},"summary":{},"results":{},"error":{"code":"\u003cstring>","message":"\u003cstring>"}}}},"exampleType":"generated"}},"exampleType":"generated"},"f7510718-c357-4ec5-b249-78e4b6d1f621":{"description":"Malformed request.","content":{"application/problem+json":{"schema":{"type":"object","description":"RFC 9457 problem details.","required":["title","status","code","request_id"],"properties":{"title":{"type":"string","example":"Document exceeds the size limit","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"status":{"type":"integer","example":422,"isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"code":{"type":"string","description":"Stable machine-readable error code.","example":"document_over_size_cap","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"request_id":{"type":"string","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"type":{"type":"string","format":"uri","description":"Link to this code's entry on the errors page. An anchor, not a path — every code lives on the one page.\n","example":"https://docs.trycactus.com/errors#document_over_size_cap","uniqueKey":"type","typeLabel":"string\u003curi>"},"detail":{"type":"string","example":"Files over 500 pages or 100 MB are rejected and not charged.","uniqueKey":"detail","typeLabel":"string"},"errors":{"type":"array","description":"Field-level validation errors, when applicable.","items":{"type":"object","properties":{"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"},"code":{"type":"string","uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"errors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"title":"Document exceeds the size limit","status":422,"code":"document_over_size_cap","request_id":"\u003cstring>","type":"https://docs.trycactus.com/errors#document_over_size_cap","detail":"Files over 500 pages or 100 MB are rejected and not charged.","errors":[{"field":"\u003cstring>","code":"\u003cstring>","message":"\u003cstring>"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"248148ca-7e7f-46ca-b25f-d51d5dfe6511":{"description":"Missing, invalid, or revoked API key.","content":{"application/problem+json":{"schema":{"type":"object","description":"RFC 9457 problem details.","required":["title","status","code","request_id"],"properties":{"title":{"type":"string","example":"Document exceeds the size limit","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"status":{"type":"integer","example":422,"isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"code":{"type":"string","description":"Stable machine-readable error code.","example":"document_over_size_cap","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"request_id":{"type":"string","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"type":{"type":"string","format":"uri","description":"Link to this code's entry on the errors page. An anchor, not a path — every code lives on the one page.\n","example":"https://docs.trycactus.com/errors#document_over_size_cap","uniqueKey":"type","typeLabel":"string\u003curi>"},"detail":{"type":"string","example":"Files over 500 pages or 100 MB are rejected and not charged.","uniqueKey":"detail","typeLabel":"string"},"errors":{"type":"array","description":"Field-level validation errors, when applicable.","items":{"type":"object","properties":{"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"},"code":{"type":"string","uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"errors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"title":"Document exceeds the size limit","status":422,"code":"document_over_size_cap","request_id":"\u003cstring>","type":"https://docs.trycactus.com/errors#document_over_size_cap","detail":"Files over 500 pages or 100 MB are rejected and not charged.","errors":[{"field":"\u003cstring>","code":"\u003cstring>","message":"\u003cstring>"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"42aa186a-638c-4fa8-95e2-c1f7316720df":{"description":"The key authenticated, but this product is not available to it. `product_not_enabled` — your account has not been enabled for this product; contact api@trycactus.com. `missing_scope` — your account has the product but this particular key was issued without it; use a key that carries the scope.\n","content":{"application/problem+json":{"schema":{"type":"object","description":"RFC 9457 problem details.","required":["title","status","code","request_id"],"properties":{"title":{"type":"string","example":"Document exceeds the size limit","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"status":{"type":"integer","example":422,"isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"code":{"type":"string","description":"Stable machine-readable error code.","example":"document_over_size_cap","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"request_id":{"type":"string","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"type":{"type":"string","format":"uri","description":"Link to this code's entry on the errors page. An anchor, not a path — every code lives on the one page.\n","example":"https://docs.trycactus.com/errors#document_over_size_cap","uniqueKey":"type","typeLabel":"string\u003curi>"},"detail":{"type":"string","example":"Files over 500 pages or 100 MB are rejected and not charged.","uniqueKey":"detail","typeLabel":"string"},"errors":{"type":"array","description":"Field-level validation errors, when applicable.","items":{"type":"object","properties":{"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"},"code":{"type":"string","uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"errors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"product_not_enabled":{"title":"product_not_enabled","value":{"type":"https://docs.trycactus.com/errors#product_not_enabled","title":"Product not enabled for this account","status":403,"detail":"Your account is not enabled for underwriting. Contact api@trycactus.com to enable it.","code":"product_not_enabled","request_id":"req_01J9Z6X2QK8N4M"}},"missing_scope":{"title":"missing_scope","value":{"type":"https://docs.trycactus.com/errors#missing_scope","title":"API key lacks the required scope","status":403,"detail":"This API key does not have the 'underwriting' scope. Use a key with underwriting access.","code":"missing_scope","request_id":"req_01J9Z6X2QK8N4M"}}},"exampleType":"examples"}},"exampleType":"examples"},"33c7e8bf-db6c-451d-9857-06b44dde9604":{"description":"Invalid property input or rejected documents.","content":{"application/problem+json":{"schema":{"type":"object","description":"RFC 9457 problem details.","required":["title","status","code","request_id"],"properties":{"title":{"type":"string","example":"Document exceeds the size limit","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"status":{"type":"integer","example":422,"isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"code":{"type":"string","description":"Stable machine-readable error code.","example":"document_over_size_cap","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"request_id":{"type":"string","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"type":{"type":"string","format":"uri","description":"Link to this code's entry on the errors page. An anchor, not a path — every code lives on the one page.\n","example":"https://docs.trycactus.com/errors#document_over_size_cap","uniqueKey":"type","typeLabel":"string\u003curi>"},"detail":{"type":"string","example":"Files over 500 pages or 100 MB are rejected and not charged.","uniqueKey":"detail","typeLabel":"string"},"errors":{"type":"array","description":"Field-level validation errors, when applicable.","items":{"type":"object","properties":{"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"},"code":{"type":"string","uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"errors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"title":"Document exceeds the size limit","status":422,"code":"document_over_size_cap","request_id":"\u003cstring>","type":"https://docs.trycactus.com/errors#document_over_size_cap","detail":"Files over 500 pages or 100 MB are rejected and not charged.","errors":[{"field":"\u003cstring>","code":"\u003cstring>","message":"\u003cstring>"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"a4f8bc94-154f-4cd9-949f-ceb103149019":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."}},"content":{"application/problem+json":{"schema":{"type":"object","description":"RFC 9457 problem details.","required":["title","status","code","request_id"],"properties":{"title":{"type":"string","example":"Document exceeds the size limit","isRequired":true,"uniqueKey":"title","typeLabel":"string"},"status":{"type":"integer","example":422,"isRequired":true,"uniqueKey":"status","typeLabel":"integer"},"code":{"type":"string","description":"Stable machine-readable error code.","example":"document_over_size_cap","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"request_id":{"type":"string","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"type":{"type":"string","format":"uri","description":"Link to this code's entry on the errors page. An anchor, not a path — every code lives on the one page.\n","example":"https://docs.trycactus.com/errors#document_over_size_cap","uniqueKey":"type","typeLabel":"string\u003curi>"},"detail":{"type":"string","example":"Files over 500 pages or 100 MB are rejected and not charged.","uniqueKey":"detail","typeLabel":"string"},"errors":{"type":"array","description":"Field-level validation errors, when applicable.","items":{"type":"object","properties":{"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"},"code":{"type":"string","uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"errors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"title":"Document exceeds the size limit","status":422,"code":"document_over_size_cap","request_id":"\u003cstring>","type":"https://docs.trycactus.com/errors#document_over_size_cap","detail":"Files over 500 pages or 100 MB are rejected and not charged.","errors":[{"field":"\u003cstring>","code":"\u003cstring>","message":"\u003cstring>"}]}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"2297ff2f-d9c9-4023-b4d6-2a7b14510000":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"ck_live_* or ck_sandbox_*","description":"Partner API key issued by Cactus.","scopes":[],"schemeName":"apiKey"}}},"servers":{"1a16f6a0-bda6-4bf3-9c8b-84185a6fb93b":{"url":"https://api.trycactus.com","description":"Production (live and sandbox keys)"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"ck_live_* or ck_sandbox_*","description":"Partner API key issued by Cactus.","scopes":[],"schemeName":"apiKey"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Partner API key issued by Cactus.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"apiKey","name":"Authorization"}],"title":"apiKey"}]},"originalFileLocation":"api-reference/openapi.yaml"},"subdomain":"cactus-10e55128","siteName":"Cactus Partner API","title":"Start an automated underwriting run - Cactus Partner API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-06T20:21:42.512Z","originalFileLocation":"api-reference/underwritings/start-an-automated-underwriting-run.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Kicks off the full automated underwriting workflow for a property: reading the submitted documents, pulling market and comparable evidence, underwriting the deal, and calculating the financial model. At least one document is required, each tagged with the role it plays. Documents are validated and accepted before the run starts; rejections are 422 and are never billed. A completed run delivers report.excel_url (the populated workbook) and results (the whole report as structured data). The default options.delivery=public_link also creates report.url (a public link anyone can open) and, if notification_email is set, emails it there. Choose private delivery to create no public link and send no email; end_user_ref is then required. Use embed-sessions for a private iframe. underwriting.completed is delivered to registered webhook endpoints. Sandbox runs complete instantly and send no email.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Cactus Partner API\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/cactus-10e55128/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/cactus-10e55128/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/cactus-10e55128/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/cactus-10e55128/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"Start an automated underwriting run - Cactus Partner API\">\u003cmeta data-mint-head property=\"og:description\" content=\"Kicks off the full automated underwriting workflow for a property: reading the submitted documents, pulling market and comparable evidence, underwriting the deal, and calculating the financial model. At least one document is required, each tagged with the role it plays. Documents are validated and accepted before the run starts; rejections are 422 and are never billed. A completed run delivers report.excel_url (the populated workbook) and results (the whole report as structured data). The default options.delivery=public_link also creates report.url (a public link anyone can open) and, if notification_email is set, emails it there. Choose private delivery to create no public link and send no email; end_user_ref is then required. Use embed-sessions for a private iframe. underwriting.completed is delivered to registered webhook endpoints. Sandbox runs complete instantly and send no email.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Cactus Partner API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://cactus-10e55128.mintlify.site/_mintlify/api/og/v2?division=Underwritings\u0026amp;title=Start+an+automated+underwriting+run\u0026amp;description=Kicks+off+the+full+automated+underwriting+workflow+for+a+property%3A%0Areading+the+submitted+documents%2C+pulling+market+and+comparable%0Aevidence%2C+underwriting+the+dea\u0026amp;theme=6ee3ac95092e49869d3cabc5\u0026amp;signature=59add40eec1feb0786f7ae287466b18efe9d55f4f3c23bea82a21cde8019b800\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Start an automated underwriting run - Cactus Partner API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Kicks off the full automated underwriting workflow for a property: reading the submitted documents, pulling market and comparable evidence, underwriting the deal, and calculating the financial model. At least one document is required, each tagged with the role it plays. Documents are validated and accepted before the run starts; rejections are 422 and are never billed. A completed run delivers report.excel_url (the populated workbook) and results (the whole report as structured data). The default options.delivery=public_link also creates report.url (a public link anyone can open) and, if notification_email is set, emails it there. Choose private delivery to create no public link and send no email; end_user_ref is then required. Use embed-sessions for a private iframe. underwriting.completed is delivered to registered webhook endpoints. Sandbox runs complete instantly and send no email.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://cactus-10e55128.mintlify.site/_mintlify/api/og/v2?division=Underwritings\u0026amp;title=Start+an+automated+underwriting+run\u0026amp;description=Kicks+off+the+full+automated+underwriting+workflow+for+a+property%3A%0Areading+the+submitted+documents%2C+pulling+market+and+comparable%0Aevidence%2C+underwriting+the+dea\u0026amp;theme=6ee3ac95092e49869d3cabc5\u0026amp;signature=59add40eec1feb0786f7ae287466b18efe9d55f4f3c23bea82a21cde8019b800\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/cactus-10e55128/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Cactus Partner API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0E7C5B\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/underwritings/start-an-automated-underwriting-run.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.trycactus.com/#organization\",\"name\":\"Cactus Partner API\",\"url\":\"https://docs.trycactus.com\"},{\"@type\":\"WebSite\",\"@id\":\"https://docs.trycactus.com#website\",\"name\":\"Cactus Partner API\",\"url\":\"https://docs.trycactus.com\",\"publisher\":{\"@id\":\"https://docs.trycactus.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run#webpage\",\"url\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run\",\"name\":\"Start an automated underwriting run\",\"description\":\"Kicks off the full automated underwriting workflow for a property: reading the submitted documents, pulling market and comparable evidence, underwriting the deal, and calculating the financial model. At least one document is required, each tagged with the role it plays. Documents are validated and accepted before the run starts; rejections are 422 and are never billed. A completed run delivers report.excel_url (the populated workbook) and results (the whole report as structured data). The default options.delivery=public_link also creates report.url (a public link anyone can open) and, if notification_email is set, emails it there. Choose private delivery to create no public link and send no email; end_user_ref is then required. Use embed-sessions for a private iframe. underwriting.completed is delivered to registered webhook endpoints. Sandbox runs complete instantly and send no email.\",\"dateModified\":\"2026-11-06T20:21:42.512Z\",\"isPartOf\":{\"@id\":\"https://docs.trycactus.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Underwritings\",\"item\":\"https://docs.trycactus.com/api-reference/underwritings/list-underwriting-runs\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Start an automated underwriting run\",\"item\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run#apireference\",\"headline\":\"Start an automated underwriting run\",\"name\":\"Start an automated underwriting run\",\"description\":\"Kicks off the full automated underwriting workflow for a property: reading the submitted documents, pulling market and comparable evidence, underwriting the deal, and calculating the financial model. At least one document is required, each tagged with the role it plays. Documents are validated and accepted before the run starts; rejections are 422 and are never billed. A completed run delivers report.excel_url (the populated workbook) and results (the whole report as structured data). The default options.delivery=public_link also creates report.url (a public link anyone can open) and, if notification_email is set, emails it there. Choose private delivery to create no public link and send no email; end_user_ref is then required. Use embed-sessions for a private iframe. underwriting.completed is delivered to registered webhook endpoints. Sandbox runs complete instantly and send no email.\",\"url\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run\",\"mainEntityOfPage\":{\"@id\":\"https://docs.trycactus.com/api-reference/underwritings/start-an-automated-underwriting-run#webpage\"},\"dateModified\":\"2026-11-06T20:21:42.512Z\",\"publisher\":{\"@id\":\"https://docs.trycactus.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.trycactus.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Cactus Partner API\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Cactus Partner API\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/underwritings/start-an-automated-underwriting-run.md","siteName":"Cactus Partner API","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":"/introduction"}]},{"tab":"API Reference","groups":[{"group":"Documents","pages":[{"title":"List documents","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/documents","href":"/api-reference/documents/list-documents"},{"title":"Register a document and get a presigned upload URL","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/documents","href":"/api-reference/documents/register-a-document-and-get-a-presigned-upload-url"},{"title":"Retrieve a document","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/documents/{document_id}","href":"/api-reference/documents/retrieve-a-document"},{"title":"Delete a document and its stored file","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml delete /v1/documents/{document_id}","href":"/api-reference/documents/delete-a-document-and-its-stored-file"},{"title":"Get a short-lived link to the original uploaded file","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/documents/{document_id}/download","href":"/api-reference/documents/get-a-short-lived-link-to-the-original-uploaded-file"}]},{"group":"Extractions","pages":[{"title":"List extraction jobs","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/extractions","href":"/api-reference/extractions/list-extraction-jobs"},{"title":"Create an extraction job","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/extractions","href":"/api-reference/extractions/create-an-extraction-job"},{"title":"Retrieve an extraction job (poll for status)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/extractions/{extraction_id}","href":"/api-reference/extractions/retrieve-an-extraction-job-poll-for-status"},{"title":"Retrieve the structured output of a completed extraction","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/extractions/{extraction_id}/result","href":"/api-reference/extractions/retrieve-the-structured-output-of-a-completed-extraction"}]},{"group":"Underwritings","pages":[{"title":"List underwriting runs","description":null,"deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings","href":"/api-reference/underwritings/list-underwriting-runs"},{"title":"Start an automated underwriting run","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwritings","href":"/api-reference/underwritings/start-an-automated-underwriting-run"},{"title":"Retrieve an underwriting run (poll for status)","description":"Live runs take ~20-30 minutes; `progress.phase` tracks the coarse\nstatus and `progress.stage` the pipeline step behind it.\n\nPass `wait` to long-poll instead of sleeping between calls. While a\nrun is active the response carries `poll_after_seconds` and a\n`Retry-After` header — use those rather than a fixed interval.\n\nA completed run carries the whole report inline: both links, the\nheadline `summary`, and the full `results` projection. This is the\nonly place `results` is returned — list responses and webhook\npayloads omit it.\n\nA run cannot exceed 4 hours; past that the worker fails it and\nrefunds every billed line in full. A run the analyst could not\nresolve without a human fails with `underwriting_needs_review` and\nis likewise refunded.\n","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings/{underwriting_id}","href":"/api-reference/underwritings/retrieve-an-underwriting-run-poll-for-status"},{"title":"Create a private report embed session","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwritings/{underwriting_id}/embed-sessions","href":"/api-reference/underwritings/create-a-private-report-embed-session"},{"title":"Download the populated Excel model","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings/{underwriting_id}/model","href":"/api-reference/underwritings/download-the-populated-excel-model"},{"title":"Outline of a finished report","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings/{underwriting_id}/outline","href":"/api-reference/underwritings/outline-of-a-finished-report"},{"title":"One section of a finished report","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings/{underwriting_id}/sections/{section}","href":"/api-reference/underwritings/one-section-of-a-finished-report"},{"title":"Editable assumptions behind a finished report","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings/{underwriting_id}/assumptions","href":"/api-reference/underwritings/editable-assumptions-behind-a-finished-report"},{"title":"What-if on a finished report","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwritings/{underwriting_id}/previews","href":"/api-reference/underwritings/what-if-on-a-finished-report"},{"title":"Request a change to a finished report","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwritings/{underwriting_id}/changes","href":"/api-reference/underwritings/request-a-change-to-a-finished-report"},{"title":"Get a change","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwriting-changes/{change_id}","href":"/api-reference/underwritings/get-a-change"},{"title":"Confirm a change and start the new version","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/underwriting-changes/{change_id}/confirm","href":"/api-reference/underwritings/confirm-a-change-and-start-the-new-version"},{"title":"Every version of a report","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/underwritings/{underwriting_id}/versions","href":"/api-reference/underwritings/every-version-of-a-report"}]},{"group":"Usage","pages":[{"title":"Usage pool balance and metered activity","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/usage","href":"/api-reference/usage/usage-pool-balance-and-metered-activity"}]},{"group":"Webhook Endpoints","pages":[{"title":"List webhook endpoints","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml get /v1/webhook-endpoints","href":"/api-reference/webhook-endpoints/list-webhook-endpoints"},{"title":"Register a webhook endpoint","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml post /v1/webhook-endpoints","href":"/api-reference/webhook-endpoints/register-a-webhook-endpoint"},{"title":"Delete a webhook endpoint","deprecated":null,"version":null,"openapi":"/api-reference/openapi.yaml delete /v1/webhook-endpoints/{endpoint_id}","href":"/api-reference/webhook-endpoints/delete-a-webhook-endpoint"}]},{"group":"API Reference","pages":[{"title":"Extraction finished successfully","version":null,"deprecated":null,"openapi":"/api-reference/openapi.yaml webhook extraction.completed","href":"/api-reference/extraction-finished-successfully"},{"title":"Extraction failed accepted documents are auto refunded","version":null,"deprecated":null,"openapi":"/api-reference/openapi.yaml webhook extraction.failed","href":"/api-reference/extraction-failed-accepted-documents-are-auto-refunded"},{"title":"Underwriting run finished with a report link","version":null,"deprecated":null,"openapi":"/api-reference/openapi.yaml webhook underwriting.completed","href":"/api-reference/underwriting-run-finished-with-a-report-link"},{"title":"Underwriting run failed","version":null,"deprecated":null,"openapi":"/api-reference/openapi.yaml webhook underwriting.failed","href":"/api-reference/underwriting-run-failed"}]}]}]},"basePath":"","title":"Start an automated underwriting run - Cactus Partner API","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-CybtLBIt.js","utils-BMLj2fvV.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-B6In562Y.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-Dr8Mfhp9.js","snippetPresets-2rmQvMVl.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-WMqJYdZj.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CJ-MlPHu.js","shallow-dY3TMRCk.js","getApiPlaygroundDisplay-v-1B2bKm.js","CodeSnippet-BDhiTB7U.js","CodeSnippets-D9hnzQcS.js","Page-C4GwDT3_.js","getPastedJson-Th2V45jI.js","icon-BQXch1W9.js","MethodPill-BCqUneP3.js","DuplicateIcon-Q_-bhurZ.js","createIcon-DUjLHRqp.js","DynamicMarkdown-B-f2cqXQ.js","SectionHeading-Da5NsV4v.js","axios-vUo_bRtp.js","Markdown-D13FWkIM.js","clsx-D3Isdib3.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-C-XZBk9h.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink--qIqmmVG.js"]}