businesses:write, deals:write, lenders:read, submissions:write and offers:read, or one with no scope restriction.
The request bodies below carry only the fields the flow needs, and the responses are trimmed. Every field, filter and response property is listed on the endpoint’s page in the API reference tab.
1
Create a business
Response 201
409 with code: "duplicate_business" and existing_id. Use that id, or repeat the call with ?force=true to create a second record anyway.2
Create a deal
Response 201
preoffer phase (stage.phase) and a deal.created webhook fires. You can also create the business inline by sending a business object instead of business_id; duplicate detection applies the same way. An optional owner object creates the primary owner or links an existing person matched by email or phone.3
Match lenders
If you have bank statements, upload them first (see Documents and uploads): once they are analysed, matching uses bank-verified revenue instead of the stated figure. Without them, matching still runs on the application data.
Response 200
view=recommended is the shortlist an underwriter would send to: score at or above the location’s threshold, with the data to back it. view=eligible also includes lenders that pass every hard gate but score lower; view=all adds disqualified lenders with their reasons. auto_eligible marks matches with no unknown gates, safe for an automated send. meta.deal.missing_fields tells you what to collect to raise confidence.4
Submit to two lenders
Submissions send email, so use an One submission is recorded per lender, with the lender-match score snapshotted as
Idempotency-Key. A retry with the same key replays the original response instead of emailing the lenders twice.Response 201
match_score, and each comes back as queued. A background worker emails it through the location’s connected mailbox, sets submitted_at and flips the status to sent (until then GET /v1/submissions/{id} shows pending); a submission.sent webhook fires per lender when the email goes out. If the location has no connected mailbox the submissions are still recorded, returned with status: "recorded" and meta.warning: "no_email_sender", for the team to send from the app. Lenders that already had a submission on the deal are left unchanged and listed in meta.already_submitted; lenders without a submissions email are listed in meta.not_sent. Pass "send": false to record submissions as pending without emailing. The first submission also moves the deal to the stage bound to first_submission_sent (Submitted on the default board).5
Read offers
Offers appear as lenders respond (To pick one, call
offer.received webhook) or when someone logs them.Response 200
POST /v1/offers/{id}/primary. That syncs the deal status to the offer’s status, and from then on status changes on that offer (contracts_requested, contracts_out, contracts_signed) move the deal stage through the location’s event bindings; GET /v1/pipeline shows them. Funding goes through POST /v1/deals/{id}/stage with event: "mark_funded", which creates the advance.Where next
Conventions
Errors, pagination, idempotency and rate limits in detail.
Webhooks
Get told when offers arrive instead of polling.
AI-first workflow
Turn these five calls into an agent.