v1.2 — Live · 26 endpoints · MCP & Custom GPT ready

The investment memo API.

Compounding fund knowledge into IC memos: a first-round memo in about 10 minutes, the full dossier in about 40. Drop into Make, n8n, ChatGPT, Claude Desktop, Cursor or any HTTP client. Your fund_thesis stays at home — only verdicts ship.

26
Endpoints
~10 min
Instant memo
MCP
Native
trigger-memo.sh
curl -X POST https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos \
  -H "Authorization: Bearer $PROPLACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fund_type": "s4bt",
    "company": { "name": "Thrust Carbon" },
    "memo_type": "detailed"
  }'

# 202 Accepted
{
  "slug": "thrust-carbon-v2",
  "url": "https://analysis.proplace.co/thrust-carbon-v2",
  "status": "queued",
  "estimated_seconds": 2400,
  "poll_url": "/v1/memos/thrust-carbon-v2"
}

↳ Memo published at analysis.proplace.co/<slug> when ready.

Quickstart — 60 seconds to your first memo

Four steps. You'll have an institutional-grade investment memo at analysis.proplace.co/<slug> in about 40 minutes (about 10 for an instant memo).

  1. 1
    Get an API token

    Email alexandre@proplace.co. We provision a personal token + onboard your fund_type in Airtable.

  2. 2
    List the funds you can target

    Confirm your fund_type is live:

    curl -H "Authorization: Bearer $PROPLACE_TOKEN" \
      https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/funds
  3. 3
    Trigger a memo
    curl -X POST https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos \
      -H "Authorization: Bearer $PROPLACE_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: $(uuidgen)" \
      -d '{
        "fund_type": "s4bt",
        "company": { "name": "Thrust Carbon", "website": "https://thrustcarbon.com" },
        "memo_type": "detailed"
      }'
    import os, uuid, httpx
    
    resp = httpx.post(
        "https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos",
        headers={
            "Authorization": f"Bearer {os.environ['PROPLACE_TOKEN']}",
            "Idempotency-Key": str(uuid.uuid4()),
        },
        json={
            "fund_type": "s4bt",
            "company": {"name": "Thrust Carbon", "website": "https://thrustcarbon.com"},
            "memo_type": "detailed",
        },
        timeout=30,
    )
    print(resp.json())  # {"slug": "thrust-carbon-v2", "poll_url": "/v1/memos/thrust-carbon-v2", ...}
    import { randomUUID } from "node:crypto";
    
    const r = await fetch("https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.PROPLACE_TOKEN}`,
        "Content-Type": "application/json",
        "Idempotency-Key": randomUUID(),
      },
      body: JSON.stringify({
        fund_type: "s4bt",
        company: { name: "Thrust Carbon", website: "https://thrustcarbon.com" },
        memo_type: "detailed",
      }),
    });
    console.log(await r.json());
  4. 4
    Poll, then read your memo

    Poll every 60 seconds — when status flips to ready, the memo is published at url.

    curl -H "Authorization: Bearer $PROPLACE_TOKEN" \
      https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos/thrust-carbon-v2
    
    # {"status": "ready", "url": "https://analysis.proplace.co/thrust-carbon-v2", "verdict": "CONSIDER", ...}
Pre-flight first with /v1/screen

Get a verdict + thesis-fit score in 10 seconds before committing 40 minutes to a full memo.

Concepts

Four objects you'll encounter. Worth 60 seconds.

fund_type — the compounding key

Every memo is written through the lens of a specific fund. The fund_type identifier resolves (server-side) to the full fund thesis, sector profile, return hurdles, M&A acquirer context, and language preference. You never send the thesis itself — your IP stays at home. Discover available fund_types with GET /v1/funds.

memo — the artifact

A memo is an institutional investment dossier (market sizing, value chain, competitive positioning, financial model, conviction, risk register, deal rationale), written by the same workers as the Proplace product. It runs two tiers:

  • instant~10 min · first-round memo: identity, thesis fit, verdict, price order of magnitude (fast and quick are accepted as aliases)
  • detailed~40 min · full dossier: market, value chain, scenarios, synergies, financial model (default)

slug — the URL key

The slug is derived deterministically from the company name (NFKD normalize → lowercase → kebab-case). A company called "Thrust Carbon" becomes thrust-carbon-v2, published at analysis.proplace.co/thrust-carbon-v2. The same company name will always produce the same slug — re-triggering overwrites the memo.

verdict — the decision

The deal roster and the memo status return the fund's verdict: CALL, CONSIDER, MONITOR, PASS (or NEW before any analysis). /screen is a financial pre-flight with its own, historical scale: CALL, CONSIDER, MONITOR, PASS, HURDLES_PASSED, OUT_OF_HURDLE, HARD_BLOCK — MONITOR with valuation_status.computable = false when the company publishes no financial data.

Authentication

Every endpoint requires a Bearer token in the Authorization header.

Authorization: Bearer pk_live_3f4a...e9c2

Create your key from your account (proplace.co/fr/compte → « Brancher Stan à vos outils »): the holder or any team member of a fund can create up to five keys, each shown once, revocable any time. A key is limited to its fund, carries scopes (funds, screen, memos, patch, approach, enrich, export) and the quotas of the plan (60 / min and 1,000 / day on Trial, 300 / 10,000 on Standard, 1,000 / 50,000 on Enterprise). Integration tokens for partners are still issued by email.

GET /v1/me tells you who you are: fund, plan, quotas, scopes and the credits balance of the fund holder. Paid calls (triggerMemo, buildModel) debit those credits: pass ?dry_run=true to get the cost without launching anything, read X-Credits-Cost and X-Credits-Remaining on the response, and expect 402 with the available packs when the balance is too low. The debit is kept only if the memo is delivered; otherwise it is refunded.

Token best practices

  • Never commit tokens. Use environment variables or your secret manager.
  • One token per integration. Easier to rotate when you offboard a service.
  • Use Idempotency-Key on POST requests. Safe to retry without duplicating memos. See error handling.

API reference

Twenty-six endpoints. The eight below are the core; the phase 2 endpoints (batch verdicts, targets, PDF, decks, skills, decisions, webhooks, news, thesis, briefs, financial models) follow. All under https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1. Full machine-readable spec: openapi.json.

GET /v1/funds

List every fund_type the caller can target.

operationId: listFunds
Show example ↓
[
  {
    "fund_type": "s4bt",
    "display_name": "Solutions for Business Travel",
    "lang": "en",
    "supports_synergy_model": true,
    "logo_url": "https://..."
  }
]
GET /v1/funds/{fund_type}

Fetch a fund's metadata + a redacted summary of its thesis (sectors, stage, ticket size). Full thesis stays internal.

operationId: getFund
GET /v1/funds/{fund_type}/deals

The enriched deal roster for a fund — every company Proplace has sourced & qualified, as canonical rows you can drop into your own CRM: verdict, conviction score, the decision-maker's name, LinkedIn, email & phone, the company LinkedIn, both memo links, and the CEO decision loop. This is the enrichment layer — it augments your existing deal-flow, it doesn't replace your tool.

operationId: listDeals
Query parameters
ParamTypeNotes
statusstringOptional. Filter by verdict — CALL, CONSIDER, MONITOR, PASS. Omit for all.
limitintegerOptional. Max rows (default 200).
Show request/response ↓
Request
curl -s \
  "https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/funds/s4bt/deals?status=CALL&limit=50" \
  -H "Authorization: Bearer $PROPLACE_TOKEN"
Response
{
  "fund_type": "s4bt",
  "count": 1,
  "deals": [
    {
      "deal_id": "rec0Abc123",
      "company_name": "Thrust Carbon",
      "website": "https://thrustcarbon.com",
      "sector": "Travel sustainability",
      "country": "United Kingdom",
      "stage": "seed",
      "linkedin_company": "https://linkedin.com/company/thrust-carbon",
      "verdict": "CALL",
      "gp_final_decision": "Advancing to a call",
      "conviction_score": 84.0,
      "summary": "Carbon accounting for corporate travel...",
      "angle": "consolidation-travel-esg",
      "founder": {
        "name": "Kit Brennan",
        "first_name": "Kit",
        "last_name": "Brennan",
        "linkedin": "https://linkedin.com/in/kitbrennan",
        "email": "kit@thrustcarbon.com",
        "phone": "+44 20 7946 0000"
      },
      "memo_url": "https://analysis.proplace.co/thrust-carbon-v2",
      "memo_pdf_url": "https://memo.proplace.co/thrust-carbon.pdf",
      "memo_type": "detailed",
      "ceo_status": "Validé",
      "ceo_decision": "yes",
      "ceo_note": "Great fit — intro me."
    }
  ]
}

Fields are best-effort: any value Proplace hasn't computed yet comes back as an empty string (or null for conviction_score), never omitted — so your column mapping is stable. Contact fields (email, linkedin) only ever carry a verified real value — an empty string means we don't have it yet, never a placeholder.

POST /v1/screen

10-second pre-flight verdict. Returns verdict, score, estimated ARR. Use before committing to a full memo.

operationId: screenDeal
Show request/response ↓
Request
{
  "fund_type": "s4bt",
  "company": {
    "name": "Thrust Carbon",
    "website": "https://thrustcarbon.com"
  }
}
Response
{
  "fund_type": "s4bt",
  "company_name": "Thrust Carbon",
  "verdict": "CONSIDER",
  "score": 75.0,
  "arr_mid_eur": 1000000.0,
  "next_step": "Call POST /v1/memos for full memo"
}
POST /v1/memos 202 async

Trigger the full memo pipeline. Returns immediately with a slug + poll_url.

operationId: triggerMemo
Show request/response ↓
Request body — minimum
{
  "fund_type": "s4bt",
  "company": { "name": "Thrust Carbon" },
  "memo_type": "detailed"
}
Response (202)
{
  "memo_id": "thrust-carbon-v2",
  "slug": "thrust-carbon-v2",
  "url": "https://analysis.proplace.co/thrust-carbon-v2",
  "status": "queued",
  "fund_type": "s4bt",
  "memo_type": "detailed",
  "estimated_seconds": 2400,
  "poll_url": "/v1/memos/thrust-carbon-v2"
}
Request body — all supported fields
{
  "fund_type": "s4bt",
  "company": {
    "name": "Thrust Carbon",
    "website": "https://thrustcarbon.com",
    "linkedin": "https://www.linkedin.com/in/kit-aspen",
    "tagline": "Carbon accounting for travel managers",
    "country": "United Kingdom",
    "company_stage": "seed",
    "founders_cofounders": "Kit Aspen (CEO, ex-GoCardless), ...",
    "funding": "€4M",
    "funding_date": "2024-03-15",
    "vc_funds": "Seedcamp, Octopus Ventures",
    "pitch_deck_url": "https://drive.google.com/...",
    "product_url": "https://thrustcarbon.com/product",
    "pricing_url": "https://thrustcarbon.com/pricing",
    "team_url": "https://thrustcarbon.com/team",
    "first_name": "Kit",
    "last_name": "Aspen"
  },
  "memo_type": "detailed",
  "lang": "en",
  "synergies_with": "rec123abc",
  "publish": "yes",
  "motive": "Strategic bolt-on for CSRD compliance moat",
  "source": "linkedin",
  "callback_url": "https://yourapp.example/proplace-callback"
}
Field reference
FieldTypeRequiredNotes
fund_typestringYesFrom GET /v1/funds
company.namestringYesDrives the slug
company.websitestring—Recommended for accurate research
company.linkedinstring—CEO/founder personal LinkedIn URL — format https://www.linkedin.com/in/firstname-lastname (NOT the company page)
company.taglinestring—One-line value prop
company.countrystring—HQ country, full name
company.company_stagestring—seed / series_a / series_b…
company.founders_cofoundersstring—Free text on the founding team
company.fundingstring—Latest round (e.g. €4M)
company.funding_datestring—Date or free text
company.vc_fundsstring—Existing investors (comma-separated)
company.pitch_deck_urlstring—Public PDF URL
company.product_url / pricing_url / team_urlstring—Override deep-research targets
company.first_name / last_namestring—CEO name hint
memo_typeenum—instant (~10 min) · detailed (~40 min, default) — fast and quick are aliases of instant
langstring—Defaults to fund.lang
synergies_withstring—Airtable record_id of a portfolio company
publishstring—Set to "yes" for the Open Deal Flow
motivestring—Strategic motive (free text)
sourcestring—Where the deal came from (twitter, linkedin, inbound…)
callback_urlstring—HTTPS URL on a public host, POSTed when the memo ends: {event: memo.ready | memo.failed, fund, slug, company, memo_type, url, error, ts}. The fund's CRM webhook gets the same event

⚡ Pass Idempotency-Key header (any UUID) to safely retry without duplicating work.

GET /v1/memos/{slug}

Poll memo status. Returns queued → building → ready (or failed).

operationId: getMemo
Show example ↓
{
  "slug": "thrust-carbon-v2",
  "url": "https://analysis.proplace.co/thrust-carbon-v2",
  "status": "ready",
  "fund_type": "s4bt",
  "company_name": "Thrust Carbon",
  "memo_type": "detailed",
  "verdict": "CONSIDER",
  "summary": "Strong CSRD compliance moat..."
}
POST /v1/memos/{slug}/patch

Surgically edit a published memo. 5 operation types: replace_section, replace_section_inner, append_to_section, prepend_to_section, replace_text.

operationId: patchMemo
Show example ↓
{
  "operations": [
    {
      "type": "replace_section_inner",
      "section_id": "conviction",
      "html": "

Conviction

New analysis...

" }, { "type": "replace_text", "find": "ARR €1M", "replace": "ARR €1.5M" } ], "dry_run": false, "commit_message": "Update conviction post-call" }

Set dry_run: true to preview the diff without pushing.

Integration recipes

Eight ways to plug Proplace into your stack. Pick one, ship in 5 minutes. Ready-made: an n8n workflow (screen a list → instant memo on MATCH → PDF), a Make / Zapier recipe, a dependency-free Python client, and llms.txt for agents.

curl

The lowest common denominator. Runs from any shell, CI job, or server.

export PROPLACE_TOKEN=pk_live_...
curl -X POST https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos \
  -H "Authorization: Bearer $PROPLACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fund_type":"s4bt","company":{"name":"Acme"},"memo_type":"detailed"}'

Python (httpx)

import os, time, httpx

API = "https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PROPLACE_TOKEN']}"}

def trigger_and_wait(fund_type: str, company_name: str) -> dict:
    r = httpx.post(f"{API}/memos", headers=HEADERS, json={
        "fund_type": fund_type,
        "company": {"name": company_name},
        "memo_type": "detailed",
    }).raise_for_status().json()
    slug = r["slug"]
    while True:
        time.sleep(30)
        s = httpx.get(f"{API}/memos/{slug}", headers=HEADERS).json()
        if s["status"] in ("ready", "failed"): return s

print(trigger_and_wait("s4bt", "Thrust Carbon"))

Node.js (fetch)

const API = "https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1";
const TOKEN = process.env.PROPLACE_TOKEN;

async function triggerAndWait(fundType, companyName) {
  const r = await fetch(`${API}/memos`, {
    method: "POST",
    headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
    body: JSON.stringify({ fund_type: fundType, company: { name: companyName }, memo_type: "detailed" }),
  }).then(r => r.json());

  while (true) {
    await new Promise(r => setTimeout(r, 30_000));
    const s = await fetch(`${API}/memos/${r.slug}`, { headers: { Authorization: `Bearer ${TOKEN}` } }).then(r => r.json());
    if (["ready", "failed"].includes(s.status)) return s;
  }
}

Make.com

HTTP module configuration — paste these fields into a Make HTTP module:

URL:           https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos
Method:        POST
Headers:
  Authorization: Bearer YOUR_TOKEN
  Content-Type:  application/json
Body type:     Raw
Content-type:  JSON (application/json)
Request body:  {"fund_type":"{{1.fund_type}}","company":{"name":"{{1.company_name}}"},"memo_type":"detailed"}
Parse response: Yes

Then chain a Sleep (30s) + HTTP GET on /v1/memos/{{2.slug}} inside a Repeater until status === "ready".

n8n

Use the HTTP Request node with these settings:

Method:        POST
URL:           https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos
Authentication: Header Auth
  Name:        Authorization
  Value:       Bearer YOUR_TOKEN
Body Content Type: JSON
Body (JSON):
  {
    "fund_type": "{{ $json.fund_type }}",
    "company": { "name": "{{ $json.company_name }}" },
    "memo_type": "detailed"
  }

For the polling loop, chain a Wait node (30s) + an IF node checking status === "ready", looping back to a second HTTP Request node on /v1/memos/{{slug}}.

Zapier

Use the Webhooks by Zapier action with these fields:

Action:    POST (Webhooks by Zapier)
URL:       https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/memos
Payload Type: JSON
Data:
  fund_type:  {{fund_type}}
  company:    {"name": "{{company_name}}"}
  memo_type:  detailed
Headers:
  Authorization: Bearer YOUR_TOKEN
  Content-Type:  application/json
Unflatten: Yes

The 202 response includes a slug you can pass to a follow-up Custom Request → GET step on /v1/memos/<slug>.

ChatGPT (Custom GPT Actions)

In your Custom GPT editor, scroll to Actions → Create new action, then:

Schema:           Import from URL
URL:              https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/v1/openapi.json
Authentication:   API Key
  Auth Type:      Bearer
  API Key:        YOUR_TOKEN
Privacy Policy:   https://proplace.co/privacy

The 26 actions appear in the GPT (listFunds, getFund, getThesis, listFundDeals, screenTargets, addTargets, triggerMemo, getMemo, getMemoPdf, buildDeck, runSkill, recordDecision, buildModel…).

Sample prompt to test: "List the funds I can target, then run a screen on Thrust Carbon for the first one."

Claude Desktop / Cursor / Windsurf (MCP)

Add this to your MCP config (e.g. ~/.claude/mcp.json for Claude Desktop, or your Cursor/Windsurf settings):

{
  "mcpServers": {
    "proplace": {
      "url": "https://alexandre-79537--sourcing-agent-fastapi-app.modal.run/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

Restart your client. 20 tools are now callable in natural language — get_me, create_fund, activate_fund, list_funds, get_fund, get_thesis, list_fund_deals, screen_targets, add_targets, get_job, screen_deal, trigger_memo, get_memo_status, build_deck, run_skill, record_decision, get_news, get_brief, build_model, patch_memo: "Screen these ten websites for my fund, then write the LOI for the Atelier Morvan memo."

Transport: streamable HTTP (JSON-RPC over POST), stateless, JSON responses. The MCP server forwards your token to the REST API: a tool can do exactly what your token's scopes allow, nothing more. Without a valid Authorization header the endpoint answers 401 / 403.

Phase 2 endpoints — everything the product promises, callable

Each endpoint is a thin facade over a function Stan already runs for your fund. Long calls return 202 with a job_id and poll_url (GET /v1/jobs/{job_id}) when they exceed ~110 s; pass ?wait=false to get the job immediately.

Endpoint What it does Body / query
GET /v1/meKey, fund, plan, quotas, credits, costs—
POST /v1/funds · POST /v1/funds/{fund_type}/activateCreate a deal flow from your website (account key, 1 credit: Stan derives the thesis and a first memo on your company), then launch the first sourcing (phone required, 30–60 min, free){website, company_name, lang} · {phone}
GET /v1/funds/{fund_type}/thesisThe thesis as Stan applies it: gate, angles, what he looks for (full for the holder's key)lang
POST /v1/funds/{fund_type}/screenMATCH / NO MATCH / DATA_GAP with the written reason on up to 10 companies; nothing written{companies:[{url}|{name, headline}], enrich} · wait
POST /v1/funds/{fund_type}/targetsAdd up to 10 companies to the deal flow, judged and deduplicated{companies:[{name_or_url}], force_reevaluate} · wait
GET /v1/jobs/{job_id}State (running / done / error) and result of an asynchronous job—
GET /v1/memos/{slug}/pdfThe memo as a committee-ready PDF (latest version)—
POST /v1/memos/{slug}/deck · GET …/deck?mode=Write the committee deck (vc, lbo, strategic), then download it (202 while building, ~30 s){mode}
GET /v1/skills · POST /v1/memos/{slug}/skills/{key}Stan's 18 skills on a memo: LOI, red flags, call prep, tech DD, KPI, board memo, 100-day plan, LP update…{lang}
POST /v1/targets/{deal_id}/decisionCEO decision: yes (validated, DD starts, webhook fires) or no (ruled out); Stan learns from the note{decision: yes|no, note}
POST /v1/targets/{deal_id}/thumbThumb up / down on Stan's verdict{kind: yes|no, message}
GET · POST · DELETE /v1/funds/{fund_type}/webhookCRM webhook of the fund (events validated, stage_changed, approach_prepared, memo.ready, memo.failed, test){url} · test
POST /v1/prepare-approach · /v1/enrich-contact · /v1/bulk-pushOutreach sequence for a target, decision-maker contact, push of a whole tab to Instantly or a webhook (scopes approach / enrich / export)see openapi.json
GET /v1/funds/{fund_type}/newsMarket watch for the thesis: content to read, recent M&A and funding dealslang
GET /v1/funds/{fund_type}/briefThe daily brief or the Monday review, as HTMLperiod: daily|weekly · lang
POST /v1/modelsFinancial model (Directive 07): ARR triangulation, projections, unit economics, returns, comparables, Excel — 1 credit{fund_type, company:{name, website}, mode: vc|strategic|lbo, deal_params}

Full request and response schemas: openapi.json (operationIds getMe, getThesis, screenTargets, addTargets, getJob, getMemoPdf, buildDeck, getDeckPdf, listSkills, runSkill, recordDecision, recordThumb, getWebhook, setWebhook, deleteWebhook, prepareApproach, enrichContact, bulkPush, getNews, getBrief, buildModel).

Pricing & credits

The API is not a separate product: it is a channel for the same three offers as proplace.co, and it runs on the same credits as your Proplace account — 1 credit = €2 excl. VAT. Reads are free and only rate-limited; calls that run AI or buy data cost credits.

Call Credits Notes
listFunds · getFund · listFundDeals · getMemo0Rate-limited only
screenDeal0Financial pre-flight, ~10 s, rate-limited
triggerMemo · instant2First-round memo, ≈ 10 min
triggerMemo · detailed10Full dossier, ≈ 40 min
buildModel1Financial model VC / strategic / LBO with Excel
screenTargets · addTargets · runSkill · decisions · webhooks · news · briefs · thesis · PDF · deck0Rate-limited only
patchMemo0Edits your own published memo
Trial · €0 Standard · €25,000 / year Enterprise · €50,000 / year
API accessOn request, one fundIncludedIncluded, one token per integration
Credits3 free credits a day, packs of 5 / 20 / 50 / 100 at €21,000 credits a year included, then packs at €23,000 credits a year included, then packs at €2, priority queue
Rate limit per token60 / min · 1,000 / day60 / min · 1,000 / day, custom on requestCustom
MCP · Custom GPT · Make / n8n / ZapierYesYesYes, with integration help (CRM push, bulk evaluation)
White-label memos & decks, custom memo template——Yes

Account keys are metered; partner tokens issued by email are not. Prices excl. VAT; the yearly offers are invoiced by bank transfer.

Errors & rate limits

HTTP status codes

Code Meaning What to do
200/202Success—
400Invalid fund_type or missing fieldCheck the available_funds field in the response body
401 / 403Token missing or invalidVerify your Authorization header
404Slug or fund_type not foundSpelling — slug is case-sensitive, fund_type is not
202 (replay)Idempotency-key replaySame Idempotency-Key within 24 h: you get the original response again, with its original status — nothing is re-executed
429Rate limit hitHonor the Retry-After header
502Upstream (memo worker / GitHub / Airtable) failedRetry. If persistent, email us.

Rate limits

Default: 60 requests/minute and 1,000/day per token. Custom quotas available on request. Every response includes:

  • X-RateLimit-Remaining-Minute
  • X-RateLimit-Remaining-Daily
  • X-RateLimit-Reset-Minute (unix timestamp)
  • X-RateLimit-Reset-Daily (unix timestamp)

Idempotency

Pass any unique key in the Idempotency-Key header on POST requests. We cache the response for 24 hours — retries with the same key return the original response without re-executing the operation.

Changelog

v1.2.0 · 2026-10-19
Account keys, credits, and the phase 2 endpoints

Keys created from the account page, limited to a fund and metered on its credits (instant memo 2, detailed 10, financial model 1; ?dry_run=true, X-Credits-* headers, 402 with packs). GET /v1/me. Batch MATCH / NO MATCH verdicts, targets added to the deal flow, jobs, memo PDF and committee decks, Stan's 18 skills, CEO decisions and thumbs, CRM webhooks, market news, daily / weekly briefs, financial models. Approach, contact and bulk-push routes documented behind their scopes. MCP: 18 tools. French presentation at /fr/api/.

v1.1.0 · 2026-10-19
Memos on Proplace's own workers, MCP with your token

triggerMemo now runs the product's instant / detailed workers (no more Make.com webhook) and memo_type accepts instant; getMemo follows the job (queued → building → ready | failed). listFundDeals documented (7 endpoints). MCP served at /mcp with 7 tools, authenticated with your token. Scopes approach, enrich, export on the outreach and CRM routes. Realistic durations, pricing & credits section.

v1.0.0 · launched
Initial public release

Six endpoints (listFunds, getFund, screenDeal, triggerMemo, getMemo, patchMemo). MCP server live. ChatGPT Custom GPT compatible.

Ready to plug Proplace into your stack?

Email alexandre@proplace.co with your fund name + use case. Most clients are live in 10 minutes — token + onboarded fund_type + one example memo.

Get your token →