Skip to main content
This walk-through takes a deal from nothing to offers in five requests. You need an API key with 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
If a business with the same EIN, or the same normalised legal name and state, already exists you get 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
The deal starts in the first stage of the 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 Idempotency-Key. A retry with the same key replays the original response instead of emailing the lenders twice.
Response 201
One submission is recorded per lender, with the lender-match score snapshotted as 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 (offer.received webhook) or when someone logs them.
Response 200
To pick one, call 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.

Related topics

Overview