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 for your organization. You create a draft deal, add a photo and the acquisition contract, publish it, and register a webhook. Then you read the events feed. Every request goes to 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 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 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 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.
The answer is 201 with the draft, cut here to the fields this step explains. The id starts with drf_.
Every money field is a whole number of dollars. 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. size_bytes is the size of the file in bytes.
The ticket says where to post the file, and with which fields.
Post the file to 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.
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 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 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.
The API stores the file and reads its fields, as the app’s wizard does. It caches the result on the draft.
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 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.
The answer carries the new deal id. It starts with mdl_. fee is the credits the publish spent.
The deal is live on Mogul. Verification starts after the publish, and the event 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 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.
The answer shows the signing secret once. Store it now. The block shows only the fields this step explains.
The endpoint starts at 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 events:read after a missed delivery, or instead of a webhook.
A list answer adds page. The feed serves 50 events a page by default, and limit= takes it to 100. The answer, cut to one event:
One event has one shape on the feed and on a webhook. Every seller-side event carries 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.