Skip to main content
The Marketplace API is in a private beta. It answers only for accounts Investorlift has enabled. Access says how to ask for one. A route shape on these pages can change before the beta ends. The changelog records every change.
On this page you act as a buyer. You search the deals Mogul shows you, read one, preview an offer and submit it. Then you answer the seller’s counter. Every request goes to https://api.investorlift.com/marketplace/v1 with an OAuth token. The token needs four scopes. marketplace:profile is for the check in step 1. deals:read is for the search and the deal read. offers:write is for the preview, the submit and the counter, and offers:read is for the offer read. The optional step 7 adds webhooks:manage or events:read.
1

Get access and a token

Access says how Investorlift enables your account. Authentication says how your client gets an access token for the audience https://api.investorlift.com/marketplace/v1.Put the token in your shell. Every snippet on this page reads it from MARKETPLACE_TOKEN.
Check what the token can do. GET /me needs marketplace:profile.
The block is the answer, cut to the fields this step explains.
sides must carry buy. trust.tier is your trust tier, and trust.next_step says what raises it. The full answer also carries caps: one row per daily cap, with limit, used, remaining and resets_at. The deal_read row is your deal budget. Trust and limits explains the tiers.
2

Search deals

The search reads the deals you see on Mogul, under the same visibility rule, 25 to a page. Filter by price and property type.
The answer, cut to one row:
Every row counts against your daily deal budget, and one deal counts once a day. Read what you need, and follow page.next_cursor until it is null. The street stays hidden until the seller shares it. While address.is_approximate is true, the coordinates sit on a coarse grid. A buyer with no attached or verified legal entity reads the first 50 deals only. trust.next_step in GET /me names the entity step.
3

Read one deal

One read counts one row against the deal budget. It adds the media, the documents, the verification state and your own offers and requests on the deal.
The answer, cut to the address block, the seller stub and your own actions:
address.status reads hidden, and street is absent, not null, until the seller shares it. An address request through POST /buy/deals/{deal_id}/inquiries asks for it. The status then reads requested. It reads approved once the seller shares the street, and declined after the seller declines. my_requests[].address_state carries the same state for each of your address requests, and it is null on a plain inquiry.address.agreement names the Non-Circumvention Agreement that the request binds to. url is where a person reads it, and accepted says if your organization accepted it. Show the agreement before the person accepts. Without the acceptance, the request answers 409 agreement_required, and the body carries the same agreement: { id, url }. Send accept_agreement: { "id": "<agreement.id>" } with the request.A new inquiry or address request answers 201. When the request exists already, the API answers 200 with the existing row and writes nothing. When the hold queue takes the request, the answer is 202.seller.phone is the Investorlift tracking number of the deal manager, or null. The seller’s own phone and email never appear. What the API returns has the rest of the object.
4

Preview an offer

An offer is a two-step write. The preview measures your terms against the deal and the seller’s requirements, and writes nothing. Send the amount, the earnest money deposit, the financing and a note of at most 500 characters.
The answer, cut to the deal stamp, four requirements and the token:
Each requirement is a code with met and blocking, and no figure the seller keeps private. can_submit is true when your terms meet every blocking requirement. standing carries your tier, the offers and previews left today, and your open chains. The preview_token proves you saw these terms and lives 5 minutes. A preview counts against your previews cap, and once a day per deal against the deal budget.If proof_of_funds_current is unmet, upload a document in three hops. Ask for a ticket at POST /buy/me/proof-of-funds/uploads with filename, content_type and size_bytes. Post the file to the ticket’s url with its fields. The ticket names the largest file in max_bytes, and its life in seconds in expires_in. Then finish at POST /buy/me/proof-of-funds with key, filename, content_type, size_bytes and an Idempotency-Key.The seller quickstart shows the same three hops for a photo. Then preview again.
5

Submit the offer

The submit sends the same terms and the preview_token. It needs an Idempotency-Key, a string of your own that the API keeps for 24 hours. The API runs every check the preview ran and refuses a deal that moved in between.
The answer is 201 with the first round of your chain, cut here to the fields this step explains. The id starts with ofr_. When the hold queue takes the offer, the answer is 202 with status: held and a hold_id, and no offer id. Trust and limits says what a held write is.
The seller gets the offer at once, in the app and on their webhooks. A repeat of the same key with the same body replays this answer with the header Idempotent-Replayed: true. Three refusals are common here.Errors lists every code, and Idempotency has the two key conflicts.
6

Follow the counter

A seller’s counter opens round 2 and marks your round countered. The event offer.countered tells you, or you read the offer.
The answer, cut to the chain:
The open round is the last one of the chain, and you act on its id. Sides alternate, so an action on your own round answers 409 wrong_side. A round that is no longer open answers 409 offer_superseded with the open round’s id. You have three answers.A counter is a two-step write like the first offer. Preview it on the open round, then send the token. The counter needs the preview_token, as the first offer does.
The counter answers 201 with the new round of your chain. When the hold queue takes the counter, the answer is 202 with a hold_id.The two other answers take one request each on the open round’s id, with an Idempotency-Key.An accept runs the two-step rule too, because it commits money. A counter counts toward your active chains, never toward the daily new-offer cap.
7

Get the events by webhook

This step is optional. A buy-side webhook endpoint gets offer.countered and offer.accepted as they occur, signed. It needs webhooks:manage, an https URL on a public host, and an Idempotency-Key.
The answer shows the signing secret once, and the endpoint starts at pending_verification. The API sends a challenge to the URL, your endpoint echoes it, and the status becomes active. Verify every delivery with webhook-id, webhook-timestamp and webhook-signature. The event id is your dedupe key, because delivery is at least once and unordered.Without a webhook, GET /buy/events?types=offer.countered,offer.accepted reads the same events in sequence order with events:read. Follow page.next_cursor and keep the last cursor. The buy side also gets offer.declined, address_request.approved and address_request.declined. It gets deal.matched for a buy box, and deal.status_changed for a deal you hold an offer on. It gets offer.held and inquiry.held when the hold queue takes one of your writes. Webhooks and events has the catalogue and the verification code.

Where to go next

Authentication

The OAuth flow at the Investorlift issuer, the scopes and the roles.

What the API returns

The deal object a buyer reads, the hidden address, the seller stub, and what never appears.

Trust and limits

The four trust tiers, the daily deal budget, the caps and how to raise your tier.

Idempotency

The key, the 24 hours, the replay header and the two conflicts.

Errors

Every code the API answers, with a body to recognise and the recovery.

Quickstart for sellers

The other side: draft, photo, contract, publish and webhook.