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.
https://api.investorlift.com/marketplace/v1
with an OAuth token.
The token needs five scopes. marketplace:profile is for the check in step 1. deals:write is for the draft, the media,
the contract and the publish. deals:read is for the read-back in step 5. webhooks:manage is for the endpoint, and
events:read is for the feed. webhooks:manage needs the owner or admin role in the organization, and a member’s token
answers 403 insufficient_role on that step.
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 Check what the token can do. The block is the answer, cut to the fields this step explains.
https://api.investorlift.com/marketplace/v1.Put the token in your shell. Every snippet on this page reads it from MARKETPLACE_TOKEN.GET /me needs marketplace:profile.sides must carry sell, and organization.role must read owner or admin for step 6. Every answer carries
meta.request_id and meta.api_version. Quote the request id when you write to support.2
Create a draft
A draft holds no property slot and costs nothing. Send the address, the property type, the prices and the condition. The
draft, the publish and the webhook send an The answer is Every money field is a whole number of dollars.
Idempotency-Key. That is a string of your own, and the API keeps it for
24 hours. The media post and the document post take none. Idempotency has the key rules.201 with the draft, cut here to the fields this step explains. The id starts with drf_.purchase_price is private: it stays on the seller side and reaches no
buyer. ready_to_publish turns true once the draft passes the publish check, and incomplete_reason says what it still
needs.The address check is advisory. If another organization holds a live deal at the address, the API answers
409 address_unavailable and names no owner. The real lock applies at publish.3
Add a photo
A file reaches a draft in three hops. First you ask for an upload ticket. Then you post the file to the object store with
the fields of the ticket. Then you register the staged key on the draft. The API never fetches a URL you supply.Ask for the ticket. The ticket says where to post the file, and with which fields.Post the file to Register the staged key on the draft. The first photo becomes the cover photo.The answer is the media list of the draft, in the order a buyer sees it. The list is one page, so
size_bytes is the size of the file in bytes.url as a multipart form. Send every entry of fields as it is, then the file as the field file,
last. The ticket is valid for expires_in seconds, and it takes a file of at most max_bytes bytes.page.next_cursor
is null.4
Attach the acquisition contract
A property deal needs the acquisition contract before publish. Upload it the same way: a ticket with The API stores the file and reads its fields, as the app’s wizard does. It caches the result on the draft.
kind set to
contract, then the multipart post. Then attach the staged key as a document of type contract. A contract takes one key
per page, so a multi-page scan sends every key in order.contract.purchase_price is private, as every contract figure is. documents lists the supporting files of the other
types, and the contract sits apart from them.5
Publish
The publish checks the draft, checks the credit balance, locks the address and creates the deal as The answer carries the new deal id. It starts with The deal is live on Mogul. Verification starts after the publish, and the event
available. It spends
the organization’s Mogul credits, as the app does, and charges no card. It deletes the draft in the same transaction. Send
an Idempotency-Key, because a publish spends credits.mdl_. fee is the credits the publish spent.deal.verification_changed follows. The
deal carries expires_at, 30 days after the publish. PATCH /sell/deals/{deal_id} changes it. Read the deal back with
GET /sell/deals/{deal_id}.Three failures are common on a first publish. Each is a problem body with a code and a recovery sentence.Errors lists every code.
6
Register a webhook
A webhook endpoint gets every event of the types it names, signed. This step needs The answer shows the signing secret once. Store it now. The block shows only the fields this step explains.The endpoint starts at
webhooks:manage and the owner or
admin role. The URL must be https on a public host, and the API follows no redirect. An endpoint on a private address
answers 422 webhook_url_refused.pending_verification. The API sends a challenge to the URL, and your endpoint echoes it in the
response. Then the status becomes active and the deliveries start. An endpoint pins api_version at create and gets
every event rendered at that version.Verify every delivery before you trust it. Read webhook-id, webhook-timestamp and webhook-signature from the
headers. The signature is an HMAC-SHA256 with the secret. It covers the id, the timestamp and the body, joined with a
full stop.Refuse a timestamp more than 5 minutes from now. Delivery is at least once and unordered, so the event id in webhook-id
is your dedupe key. Webhooks and events has the verification code.7
Read your events feed
The feed is the replay path. It holds the same events a webhook delivers, in sequence order, for 30 days. Read it with
A list answer adds One event has one shape on the feed and on a webhook. Every seller-side event carries
events:read after a missed delivery, or instead of a webhook.page. The feed serves 50 events a page by default, and limit= takes it to 100. The answer, cut
to one event:deal_id and the id of the
resource, so your CRM correlates it. The buyer block carries the name, the entity and buyer_id. The email and the phone
ride on it only when the endpoint’s creator holds contacts:read. actor.id names a member of your organization as
mbr_. It is null here, because the buyer acted.Follow page.next_cursor until it is null, and keep the last cursor. The cursor is a sequence position, so types=
changes the filter and keeps the cursor valid. from= names an instant for the first read. A page never includes an
event newer than a short lag, so a late commit never falls behind your cursor.Where to go next
Authentication
The OAuth flow at the Investorlift issuer, the scopes and the roles.
Webhooks and events
The event catalogue, the signature, the retries and the replay rule.
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 buyers
The other side: search, preview, submit and counter.
Terms
The Marketplace API Terms you accepted on the consent page.