How the objects fit together
The endpoint reference lists every field. This page is the map: what each object is, how the objects hang together, and which id you follow to get from one to the next.
This API is in beta. Any endpoint can change in a breaking way without notice, so watch the changelog.
Your brokerage
Everything a key can reach belongs to one brokerage, and the key acts as one broker in it.
GET /me tells you which. A key never reaches another brokerage, and it
never does more than the broker who made it. See Authentication.
Users are the brokers and staff. GET /users lists them with their
licences. Any field that names a person (owner_id on a contact, assigned_broker_id on a deal,
assignee_user_id on a task, author_id on a note) is a user id that GET /users/{id} resolves.
A user carries identity only: name, email, role, and whether the account is active. Phone numbers
and booking handles stay out, because several of them work like credentials.
Most ids come with a readable name beside them, such as assigned_broker_name on a deal or
assignee_name on a task. Store the id and show the name; the name can change. Every record also
has an object field ("deal", "contact", "task") so you can tell types apart in one list.
Teams group brokers. GET /teams lists them, and each has exactly one
owner. What a key sees depends on the teams its broker belongs to.
Contacts and leads
A contact is a person or a company in the book; kind tells you which. types says what they
are to you (borrower, referral partner, realtor), and one contact can be several at once.
Contacts carry more than the main email and phone:
- Addresses through
/contacts/{id}/addresses: the broker's own addresses for the person (home, work, mailing, cottage). Exactly one is primary. The first one you add becomes primary, andis_primary: trueon another moves it. The residence history on a mortgage application is a separate, read-only record. - Methods through
/contacts/{id}/methods: extra emails and phones, fax numbers, and social profiles. A social profile returns aurlbuilt from what the broker typed. - Relationships through
GET /contacts/{id}/relationships, worded from that contact's side.
To find a person before you create one, send email or phone to GET /contacts or GET /leads.
Email ignores case, phone compares the last 10 digits, and both check every email and phone on the
contact. No match is an empty list. Capture leads walks through this.
Duplicates, merge, and archive
GET /contacts/duplicates lists sets of contacts that share an email, a
phone, or a name. To merge one, pick the contact to keep and send the others:
Code
Deals, notes, documents, and history move to the contact you keep. A merge can't be undone. After
it, GET /contacts/{id} on a merged id returns 410 CONTACT_MERGED with details.merged_into_id,
so you can replace the id you stored.
POST /contacts/{id}/archive takes a contact out of the lists and sets archived_at. The contact
keeps its history, GET /contacts/{id} still returns it, and a later import or lead with the same
email finds it. POST /contacts/{id}/unarchive puts it back.
Leads
A lead is an inbound enquiry that is not a deal yet. Every lead has a contact, and the name,
email, and phone live on that contact. status is open, archived, or converted.
POST /leads/{id}/convert starts a deal, and the lead then carries it as
converted_deal_id.
Custom fields
A brokerage keeps its own custom fields on contacts and deals.
GET /custom-fields lists them with their key, type, and options.
A field with a default_value starts with that answer on each new record. A lead has no fields of
its own: it uses its contact's, and you can set them with custom_fields on POST /leads.
Filter a list by a field with custom_field[<key>]=<value> on GET /contacts, GET /leads, or
GET /deals, for example GET /v1/leads?custom_field[lead_source]=Google. To create or change the
fields themselves, see Configure your workspace.
Contact statistics
GET /contacts/{id}/statistics says how a contact stands in the book. The
figures are computed on each read from the deals your key can see, and a deal counts once for each
borrower on it.
Funded volume uses the commission's funded amount when the broker recorded one, and the
application's loan amount otherwise. A funded deal with neither counts in
funded_deals_without_amount and adds nothing, so while that count is above zero the volume is a
floor, not a total. Year-to-date uses the brokerage's calendar year in timezone. A contact is a
repeat client once two of their deals have funded, and last_touch is the latest note, message, or
deal change.
Pipelines, stages, and deals
A deal is a mortgage file. It sits in one place on one pipeline:
board_idis the pipeline, resolved byGET /pipelines/{id}.stage_idis a stage on that pipeline. Stages come inside the pipeline, in board order.stage_nameis a copy of the stage label, so a list view needs no second call.
Every brokerage sets up its own pipelines, so read stages from GET /pipelines rather than
hardcoding a name or an id. A pipeline BrokerPlus created has a key (for example historical,
where funded and past deals go); look it up by key, not by name. A stage with exclude_from_book
holds paid-out mortgages, and a deal on a stage with stops_automated_outreach gets no automated
messages. allowed_deal_types says which deals land on a pipeline by default; it doesn't stop a
deal from moving there.
POST /deals opens a deal for the key's broker. Without board_id, it lands on the broker's default
pipeline for its type, on the first stage. If you name a pipeline, it must belong to the broker's
team and stage_id must be on it. Attach borrowers with contacts, each with a role.
PATCH /deals/{id} can move a deal only to a stage on its own pipeline. The API refuses a stage
from another pipeline, because the deal would drop out of every board view.
GET /deals/{id}/stage-requirements tells you what a stage needs before you move a deal into it.
Copy, archive, and restore a deal
POST /deals/{id}/duplicate makes a new deal with the same people and primary application, on the
first stage of the same pipeline. carry_participants: false copies only the primary applicant,
type gives the copy another deal type, and archive_original: true archives the original once the
copy exists. Submissions, funding, compliance, and documents are not copied.
DELETE /deals/{id} archives a deal, and POST /deals/{id}/restore brings it back. Tasks the
archive cancelled stay cancelled.
Flags
A flag paints a deal's card red on the board. GET /deals/{id}/flags lists the flags that are up,
each with a plain-words reason and a stable reason_code. raised_by is broker for the one flag
a broker raises by hand, automation for a Pulse automation, or brokerplus for BrokerPlus itself.
POST /deals/{id}/flags raises the broker's flag (send it again to change the words), and
POST /deals/{id}/flags/{flagId}/clear takes it down. Other flags are read-only: clearing one
returns 409 SYSTEM_FLAG. Flags are internal; no client sees them.
The deal's checklist
Each team keeps a checklist of steps for its files, such as "appraisal ordered" or "commitment
signed". GET /deals/{id}/checkpoints lists the team's steps with their value on the deal: true
for done, false for not done, and null when nobody has set it.
PATCH /deals/{id}/checkpoints/{checkpointId} sets one step, and value: null clears it.
Find a deal by an id from another system
A deal imported from Velocity, Filogix, or Finmo keeps its old id in external_references, and the
lender's file number sits in lender_file_ref. Look one up with
GET /deals?external_reference=<id> (add source to name the system) or
GET /deals?lender_file_ref=<number>. Both match the whole value exactly, and an empty list means no
deal has that id.
What hangs off a deal
| Sub-resource | Endpoint | What it is |
|---|---|---|
| Mortgage application | GET /deals/{id}/application | The loan: amount, term, amortization, rate, payment, and ratios. |
| Subject property | GET /deals/{id}/property | The property that secures the loan. |
| Applicants | GET /deals/{id}/applicants | Everyone on the application, with jobs and income. |
| Financials | GET /deals/{id}/financials | What the applicants own and owe, and the down payment. |
| Other properties | GET /deals/{id}/other-properties | Real estate the applicants already own. |
| Terms history | GET /deals/{id}/application/terms-history | Each change to the loan terms, with who and when. |
| Documents | GET /deals/{id}/documents | The files on the deal. See Documents. |
| Conditions | GET /deals/{id}/conditions | What a lender needs before the deal funds. |
| Participants | GET /deals/{id}/participants | The borrowers and the partners on the deal. |
| Deal team | GET /deals/{id}/team | The users who work the deal, by role. |
| Commission | GET /deals/{id}/commission | What the brokerage earns, and how it is split. |
| Consents | GET /deals/{id}/consents | What each party authorized. |
| Notes and tags | GET /deals/{id}/notes, /deals/{id}/tags | Commentary and your own labels. |
| Stage history | GET /deals/{id}/stage-history | Every stage move, newest first. |
| Activity | GET /deals/{id}/activity | The trail of messages, calls, notes, and changes. |
Participants and partners
A participant is a contact on a deal with a role, and is_partner splits the roles in two:
- Borrower roles are on the application:
primary_applicant,co_applicant,guarantor, andpower_of_attorney. - Partner roles are professionals on the file:
realtor,lawyer,appraiser,lender_contact,underwriter_contact,credit_assistant,insurance,financial_planner,accountant,builder, orother(with your own word inrole_label).
A contact holds one role per deal. Add and remove participants, and change a partner's role, through
/deals/{id}/participants. A borrower's role belongs to the application and
doesn't change here.
A partner on a deal is not the same as a partner in the book: types on a contact says the person
refers business to you, while the role on a deal says what they do on one file.
Referral partners
A deal's referral_partner is who sent you the deal. Set it with
POST /deals/{id}/referral-partner, using contact_id for a contact or name for someone who isn't
one. A contact becomes a partner the first time you name them.
GET /referral-partners reads the partner book with the same
figures as the Partners page. A partner's id is their contact id, or source: plus an id for a
name-only partner; pass it as it is to GET /referral-partners/{id}. People count on the day they
were referred, money on the day the deal funded. The book covers every team, but a key limited to
some teams sees only the people and deals those teams can read. To create or change partners, see
Configure your workspace.
Teams and members
A team is one broker's crew. The broker owns it, and everyone else is a member, with the
brokerage's own title for the seat (underwriter, assistant, submitting broker).
GET /teams/{id}/members reads the roster. Membership is set up in
BrokerPlus, not through the API.
Commission
A commission is what the brokerage earns on a funded deal, one per deal, read and changed through
/deals/{id}/commission. Every figure is what the broker typed; the API
doesn't derive a fee from a rate sheet.
- The top level holds the lender, funded amount, finder's fee, bonus, buydown, and gross.
- A line item says where part of the money comes from. When line items exist,
gross_amountis their sum less the buydown, and the API keeps it that way. - A split allocates the gross to a payee: a broker, the house, a franchise, or a referral partner. It says who is owed a share, not that it was paid.
Commission has its own access rule. The key's broker can read it as the deal's broker, as a brokerage
admin, or as a team member with the view_commission grant. Anyone else gets
403 COMMISSION_ACCESS, even on a deal they can change. Changes post to the brokerage's connected
accounting system, and revision goes up on each one.
Consents and communication preferences
A consent records that one party on one deal authorized one thing: a credit pull, a lender
submission, privacy processing, electronic delivery, or a mortgage protection plan transfer. Read and
add them through /deals/{id}/consents, and take one back with
POST /deals/{id}/consents/{consentId}/revoke. Consents are never deleted, so the file always shows
what the brokerage held at the time. When the client agreed to written text, text and
text_version keep it as it read then. A credit_pull consent lapses 30 days after it is given.
A consent is a record only; it doesn't start a pull or a submission.
A communication preference is the client's standing on commercial email and SMS. It belongs to
the person, not a deal: GET /contacts/{id}/communication-preferences.
Email has three categories (all_commercial, marketing, equity_reports), and withdrawing from
all_commercial stops every commercial message. SMS has one switch. No record means implied, the
default for a client in the book.
PATCH on the same path takes one action per category: opt_out records a withdrawal, opt_in
clears one without recording express consent, and express records express consent with your
source. A suppression (a hard bounce, a complaint, a STOP reply) shows as suppressed, and the
API doesn't change it.
Applicants and financials
Every rate and ratio here is a percent; see Units and formats.
An applicant is one person on the application, with role primary, co_applicant, or
guarantor. Each carries their jobs and any other income. Their name and contact details live on
contact_id. The API never returns a social insurance number.
Financials are the money on the deal: assets, liabilities, and down payment sources. The API
never returns an account number. A liability with from_credit_bureau: true came from a credit
report, not from the applicant. Consumer report data has its own redistribution rules, so check
your obligations before you store or forward it.
Calculated figures on the application
GET /deals/{id}/application returns the figures BrokerPlus calculates from the rows, the same ones
the broker sees:
gds,tds, andltv(null when there isn't enough data), andratio_qualifying_rate, the rate those ratios use.total_loan_amount: the loan plus the insurance premium, when the premium is added to the loan.insurance_premium,insurance_premium_rate, andinsurance_premium_added_to_loanfor mortgage default insurance.stated_fees: the fees the lender stated.
The property adds appraised_value and appraisal_date. These figures are read-only; change the
rows they come from.
The rest of the application
The application, the property, and their rows carry the same details the broker fills in on the
deal. The application has the loan, charge, and repayment types, the buyer type, the legal and
closing costs, and the purchase stage. The property has heating, water, parking, zoning, size,
purchase history, taxes, and rental costs. An applicant has an honorific, a suffix, sex, and a
language. A job has the employer's address and the business type. A liability has its debt, charge,
and payout types, plus property_id when it is the mortgage on another property.
PATCH /deals/{id}/application and PATCH /deals/{id}/property change these, as do the row
endpoints below. The first application update creates the application on a deal that has none. A
coded field takes the numeric code it returns on read. product_code and tenure are read-only,
because the origination system sets them.
Edit the application one row at a time
Each applicant, job, income source, address, phone number, asset, liability, and other property
has its own POST,
PATCH, and DELETE. A request changes one row and leaves the rest alone, and BrokerPlus
recalculates the totals and ratios straight away.
| Row | Endpoint |
|---|---|
| Applicant | /deals/{id}/applicants/{applicantId} |
| Job and its pay | /deals/{id}/applicants/{applicantId}/employments/{employmentId} |
| Other income | /deals/{id}/applicants/{applicantId}/income-sources/{incomeSourceId} |
| Address | /deals/{id}/applicants/{applicantId}/addresses/{addressId} |
| Phone number | /deals/{id}/applicants/{applicantId}/phones/{phoneId} |
| Asset | /deals/{id}/assets/{assetId} |
| Liability | /deals/{id}/liabilities/{liabilityId} |
| Other property | /deals/{id}/other-properties/{propertyId} |
To create a row, POST to the path without the last id. To add an applicant, first put the contact
on the deal as a borrower with POST /deals/{id}/participants, then send their contact_id.
This adds a job that pays $4,250 twice a month:
Code
An amount is per period, not per year. In a PATCH to a job, incomes is the full list: include
the id of each line to keep, and leave out each line to remove. A few rows push back:
- A liability from a credit report is read-only:
409 FROM_CREDIT_BUREAU. - You can't remove the primary applicant:
400 PRIMARY_APPLICANT. - An applicant must be on the deal as a borrower:
400 NOT_A_BORROWER.
An applicant's addresses are their address history: one current address, each earlier home as a
previous address with its started_on and ended_on, and a correspondence address when their
mail goes somewhere else. Lenders ask for about three years of history. An applicant's phone numbers
are the ones the lender sees, and they are separate from the contact's own phone numbers.
Credit notes
GET /deals/{id}/credit-notes lists the broker's own notes on the credit of the people on the deal,
one per person. PATCH /deals/{id}/credit-notes/{contactId} writes one, as the credit panel on the
deal does. The first write creates it. These are the broker's words only: no credit score and no
credit report goes out over the API, and a score the broker entered in BrokerPlus is kept as it is.
Lender commitments
When the lender sends its commitment, BrokerPlus reads the terms from the PDF: the amount, the rate, the term, the payment, the fees, and the prepayment and portability terms. The broker checks them against the PDF and corrects what was read wrong. Only reviewed terms go on the cost of borrowing disclosure that the client signs.
GET /deals/{id}/commitmentslists what was read, newest first. Each commitment has itsterms, with the broker's corrections applied, and thecost_of_borrowingworked out from them. A value the PDF does not state isnull.terms.sourcessays which page each value came from.POST /deals/{id}/commitmentsreads a PDF. With no body, it reads the PDF the lender sent with its latest decision. For a lender that sends none, upload the commitment as a document and send its id indocument_id. Reading the same PDF again replaces its terms and clears the review.POST /deals/{id}/commitments/{commitmentId}/reviewmarks the terms as checked. Send corrections inedits, for example{ "edits": { "interest_rate": 4.79 } }. They replace the corrections of an earlier review.
Rates are percents (see Units). Nothing here sends anything to the client.
Value history of the deal's property
GET /deals/{id}/property-valuations lists each valuation of the property the deal's mortgage is
on, newest first, with its estimate, its assessment, and its source. It is the home value trend on
the client's equity report, and BrokerPlus adds to it each month while the client gets reports. A
broker's own value, set with property_value on the opportunity, is not in this list.
Creditor life insurance
GET /deals/{id}/life-insurance returns the deal's creditor life insurance: whether the broker
offered it, what the client said in outcome, and where the application is with the insurer in
status. POST /deals/{id}/life-insurance/outcome records the client's answer, as the insurance
panel on the deal does. Sending the application or asking for a quote shares the client's file with
the insurer under their consent, so the broker does that in BrokerPlus.
Valuation history of an other property
GET /deals/{id}/other-properties/{propertyId}/valuations lists each valuation of the property,
newest first, with its estimate, its assessment, and its source. change_12mo shows how the estimate
changed over the last year, as a percent. It is null until there are two estimates to compare.
POST /deals/{id}/other-properties/{propertyId}/refresh-valuation asks the valuation service for a
new estimate, the same as the refresh button in BrokerPlus. The request returns 202 and the
valuation runs in the background. The property must have a street address, or the API returns
400 NO_ADDRESS. Send an Idempotency-Key: a retry with the same key does not ask again.
Debt consolidation analysis
A debt consolidation analysis compares three ways to pay out the client's other debts: a refinance, a home equity line of credit, and a reverse mortgage. It is the same analysis as the Debts tab in BrokerPlus. It reads:
- Each debt on the deal that has a
debt_type. Setdebt_typewhen you add a debt withPOST /deals/{id}/liabilities. A debt with nodebt_typeis not in the analysis. - The other properties on the deal.
- The balance and the property value on the deal's opportunity. Set the value with
PATCH /opportunities/{id}if BrokerPlus has no estimate.
POST /deals/{id}/consolidation-analyses runs the analysis and saves it. To replace the default rate
for an option, send new_mortgage_rate_pct, heloc_rate_pct, reverse_mortgage_rate_pct, or
rental_heloc_rate_pct, as a percent. BrokerPlus sends nothing to the client.
An analysis never changes. GET /deals/{id}/consolidation-analyses lists them newest first, so the
first one is the deal's current analysis. In each analysis, status_quo is the client's position if
nothing changes, options lists each option that BrokerPlus compared, and
recommended_option_index points to the recommended option. Every rate and the loan-to-value ratio
are percents.
Terms history
GET /deals/{id}/application/terms-history lists each change to the rate, term, amortization, and
other loan terms, oldest first, with the old value, the new value, who changed it, and when. Use
updated_since to read only the newer changes.
Conditions
A condition has two statuses. status is your team's answer; lender_status is the lender's,
and a condition your team considers done can still be outstanding with the lender. source says who
asked for it.
You change status with POST /conditions/{id}/satisfy, POST /conditions/{id}/waive, or
PATCH /conditions/{id}. lender_status belongs to the lender, and BrokerPlus refreshes it on each
decision poll.
POST /deals/{id}/conditions adds a condition the way the deal's Conditions tab does, and files a
task to decide it that completes when the condition is satisfied or waived. assignee_role says who
owes it (broker, borrower, lawyer, credit_assistant, realtor, insurer, or your own value),
and assignee_contact_id names the person when they are in your book. To explain open conditions to
someone on the deal in plain language, use POST /deals/{id}/condition-requests; it sends the letter
at once. See Ask a client for something.
documents lists the documents attached to a condition as what answers it. They go to the lender
with the condition. POST /conditions/{id}/documents attaches more, as the attach on the Conditions
tab does. Each document has to be on the condition's deal. Attaching changes nothing else: satisfy
the condition when it is done.
Scheduling
A meeting type is a booking link a broker shares with clients. GET /meeting-types lists the
key's broker's meeting types and their teams' shared ones. GET /availability returns the open start
times of one meeting type, calculated the way the booking page does: each host's hours in their own
time zone, with split shifts, blocked days, buffers, minimum notice, and calendar busy times.
POST /appointments/book books a contact into a time that GET /availability returned.
POST /appointments/{id}/reschedule moves a booking to another open time with the same host, and
POST /appointments/{id}/cancel cancels it. All three act now, email the client, and return the
booking. A key with the no_sending limit cannot use them. If the time is taken first, the call
returns 409 and nothing is sent. GET /appointments/{id}/booking reads the booking, including
after a move or a cancellation.
/appointments itself is the broker's calendar. Creating, changing, or deleting an appointment there
sends nothing to a client. To change meeting types, hours, and blocked days, see
Configure your workspace.
Submissions
A submission is a deal a broker sent to a lender, with the lender and status. source says what
sent it:
brokerplus: BrokerPlus sent it. Read the lender's answers throughGET /submissions/{id}/decisions.finmo: the brokerage's connected Finmo account sent it, and BrokerPlus mirrors it. The lender's answer is inlender_status, and the requested terms are inloan_amount,interest_rate, andterm_months. A Finmo submission has no decisions endpoint, andattemptis null.
A submission with simulated: true was a test that never reached a lender, so leave it out of
reports. The API reads submissions; it never sends one.
Opportunities
An opportunity is a mortgage your brokerage tracks for a renewal or a refinance, with the
balance, the penalty to break it, and the savings from a move. POST /opportunities adds one by hand,
the same as Add Client on the book: BrokerPlus links the client by email or creates the contact,
and makes a deal for the mortgage. Each call creates one, so send an Idempotency-Key.
effective_penalty is the penalty that applies: the greater of ird_penalty and
three_month_penalty, unless the broker entered one from a lender payout statement. A timestamp in
outreach_unsubscribed_at means the client opted out of equity reports, and nothing else.
Where the broker typed over a figure BrokerPlus had, such as comparison_rate or
property_bedrooms, the opportunity carries the broker's figure. best_option_pin is the option the
broker chose to show the client, or null.
Find opportunities
GET /opportunities takes the same filters as the book in BrokerPlus, and you can combine them.
This request finds the variable-rate mortgages that mature in the first quarter of 2027, soonest
first, and leaves out the ones the broker dismissed:
Code
| Filter | Returns only |
|---|---|
maturity_from, maturity_to | The mortgages that mature in this window. Both days are included. |
dismissed | true: the dismissed ones. false: the ones still on the book. |
archived | true: the mortgages whose term ended. false: the live ones. |
opportunity_type | renewal, pre_renewal, ird, or both. |
product_type | fixed, variable, arm, or heloc. |
start_year | The mortgages that started in these years, for example 2021,2022. |
assigned_broker_id | The mortgages on deals assigned to this broker. |
monthly_reports_enabled | true: the clients enrolled in equity reports. false: the rest. |
Separate several values with commas. sort takes maturity_asc, maturity_desc,
last_client_contact_desc, or last_client_contact_asc; without it, the most recently changed
opportunity is first. A sync with updated_since always reads in updated_at order, so it can't
take sort. The filters work with a sync.
Correct what the mortgage carries
BrokerPlus didn't arrange these mortgages, so the balance, rate, and payment are only as current as
the last statement. PATCH /opportunities/{id} corrects them. A deal doesn't carry its
opportunity's id; find it with GET /opportunities?deal_id=cm7x2q1k80001 (there is at most one).
Code
Code
Use interest_rate for a fixed rate and prime_adjustment for a variable one, where -0.5 means
prime minus 0.50%. A balance you send becomes the new anchor: BrokerPlus pays it down from that day,
neither the nightly recalculation nor an import overwrites it, and balance_is_manual reads true.
Send null to hand it back. Penalties, savings, and the target rate follow from these figures, so one
request can change several fields. The original principal, maturity date, and amortization belong to
the deal, not here.
Act on an opportunity
These do the same as the menu on an opportunity in BrokerPlus:
| Request | What it does |
|---|---|
POST /opportunities/{id}/convert | Starts a new working deal with the borrowers and mortgage facts. |
POST /opportunities/{id}/dismiss | Takes the mortgage off the book and stops its equity reports and signals. |
POST /opportunities/{id}/restore | Puts a dismissed mortgage back. |
POST /opportunities/{id}/snooze | Hides it until until, and reminds the broker that morning. |
POST /opportunities/{id}/unsnooze | Ends the snooze. |
Dismiss, restore, and unsnooze are safe to repeat. Convert creates a deal every time (a client can
refinance twice), so send an Idempotency-Key; the response is the new deal. A deal on a stage that
locks it refuses everything except convert with 403 DEAL_LOCKED.
The equity reports about a client are at GET /equity-reports?contact_id=.... See
Equity reports.
Notes
A note has the same shape on a contact and on a deal. Notes thread one level deep: a note can carry a
parent_id, and the API refuses a reply to a reply rather than flattening it. pinned is what the
app shows at the top.
PATCH /contacts/{id}/notes/{noteId} and PATCH /deals/{id}/notes/{noteId} change the words, the
pin, or the kind. A pin alone doesn't change updated_at. Anyone who can edit the contact or deal
can edit its notes, as in BrokerPlus. DELETE removes the note and its replies for good.
Task notes work the same at PATCH /tasks/{id}/notes/{noteId}, without a kind. Only the author can
delete a task note; anyone else gets 403 NOT_AUTHOR.
A new note has the kind general unless you send type. The kinds are at
Note types.
Mentions, reactions, and files
These work the same on a contact note and a deal note. The paths below use deals.
- Mentions. To mention a teammate, put
<span data-mention="USER_ID">@Name</span>in the body.GET /deals/{id}/notes/mentionablelists the teammates that a note can mention. Each one gets a notification, as in BrokerPlus.mentionson the note lists who was named. - Reactions.
POST /deals/{id}/notes/{noteId}/reactionswith{"emoji":"👍","active":true}adds the reaction of the key's broker, and"active":falsetakes it off. Sending it again changes nothing.reactionson the note sums them per emoji. - Files.
POST /deals/{id}/notes/{noteId}/attachmentsattaches a PDF of at most 25 MB, asmultipart/form-datain afilefield or as JSON withfile_nameandcontent_base64.attachmentson the note lists the files, andGET /deals/{id}/notes/{noteId}/attachments/{attachmentId}gives a download link that works for five minutes. A key with theno_documentslimit gets403on both.
Drafts
A draft is a message written for the broker to review. POST /contacts/{id}/drafts files an sms
or email draft into the review queue of the key's broker with status pending_review, exactly like
a draft BrokerPlus writes. The broker reads it in BrokerPlus and sends, edits, or rejects it.
Use a draft when your system writes the words and a person should read every one before a client
does. To send a draft as it is written, use POST /drafts/{id}/send. To send a message without a
review, use POST /contacts/{id}/messages. Both send now, from the broker's connected mailbox or
phone number, and a key with the no_sending limit gets 403. If you only want the broker to do
something, create a task instead.
Code
Code
The response is shortened here. An sms draft has no subject and at most 1600 characters. An
email draft needs a subject.
Follow a draft after you file it
GET /drafts lists the drafts your key filed, newest first, and GET /drafts/{id} reads one. Filter
with status, channel, contact_id, deal_id, or updated_since. Drafts the broker wrote in
BrokerPlus aren't listed.
status | What it means |
|---|---|
pending_review | Waiting in the broker's review queue. |
scheduled | Set to go out at scheduled_at. |
sent | Sent. communication_id is the message the client got. |
discarded | The broker rejected it. |
failed | A scheduled send didn't go out. |
The broker can edit a draft before it goes, so subject and body show what the client got.
Change, schedule, or discard a draft
PATCH /drafts/{id} changes a draft that waits for review, and POST /drafts/{id}/discard throws it
away. POST /drafts/{id}/schedule sets it to go out at send_at, and
POST /drafts/{id}/unschedule stops it. To draft a reply to a message instead of a new message, see
Reply to a client.
Tags
Contacts and deals have separate tag vocabularies: GET /contact-tags and GET /deal-tags. They
share a shape, not a namespace, so a deal tag means nothing on a contact.
Putting a tag on a record and taking it off are both idempotent. Adding the same tag twice leaves one, and removing a tag that isn't there still succeeds. To create or change tags, see Configure your workspace.
Lenders
GET /lenders lists the lenders your brokerage can use. source says
where each comes from:
brokerplus: the brokerage's own catalogue, withis_prime,is_alternative, andis_private.finmo: mirrored from the brokerage's connected Finmo account. Finmo folds the product line into the name, so "First National - Prime" and "First National - Excalibur" are two lenders.lender_typecarries Finmo's classification.
A lender with under_maintenance: true can't take a submission right now. A submission's
lender_id resolves against the lender with the same source; send source=brokerplus or
source=finmo to list one side. Rate sheets and compensation aren't published.
Tasks
Tasks are an action queue, not a general to-do list. Each has a type for the kind of work and a
priority that orders the list, and it can link to a deal, a contact, or both. BrokerPlus files many
tasks on its own.
You can create, change, assign, complete, cancel, and reopen tasks, and read and write their notes
(which a client never sees). A new task takes the team of its deal or contact, or the broker's own
team. An assignee must be eligible for that team and deal, by the same rule as BrokerPlus, or the API
returns INVALID_ASSIGNEE. A task with no assignee waits until somebody takes it.
POST /tasks/bulk completes, cancels, or reopens up to 200 tasks at once and returns updated_ids
and skipped_ids. A task already in that state is skipped, and so is an approval task, which only
the broker decides (cancel or reopen one directly and you get 409 APPROVAL_TASK).
POST /tasks/batch creates or updates up to 100 tasks; see Idempotency and batch.