CapScout
How it worksFeaturesPricingFor teamsLearn
Contact Log in Start for free
How it worksFeaturesPricingFor teamsLearn Contact Log in
Developers

Connect CapScout to the tools you already run

API v1 · Team plans · times are ISO 8601 in UTC

CapScout's CRM has a small API and signed webhooks. Use them to bring leads in from anywhere, keep another CRM in step, or build on what happens in your book. People flow in from your other tools. Investor activity (reports sent and opened, stage moves, deals) flows out from CapScout.

Get a key

An Owner or Admin creates keys in Settings → Integrations. A key is shown once. It acts as the member who made it: it sees the contacts they see, and it stops working if they leave the team or stop being an Owner or Admin. Send it on every request:

Authorization: Bearer csk_live_…

The base URL is https://api.capscout.ai/v1/api. Requests and responses are JSON. A key gets 120 requests a minute.

Endpoints

GET /me

Who this key is: the team, the key and the member it acts as. Use it to test a connection.

POST /leads

Add a lead from anywhere. It is routed, given its first follow-ups and announced to its agent like any other lead.

GET /contacts

The contacts the key’s member can see, newest change first. Filter by email, phone, stage, search or updated_since.

POST /contacts

Create a contact, or update the one already under that email: 201 for new, 200 for existing. An update sets name and phone and adds tags. Notes, stage, owner and visibility are set on create only.

GET /contacts/{id}

One contact.

POST /contacts/{id}/touches

Log a call, text, email, meeting or note on the person’s timeline. Send external_id and the same one files once.

POST /contacts/{id}/stage

Move the person to a stage. The move is logged and the stage’s follow-ups start.

GET /events

What happened in the book, newest first. Filter by kind. With since_id you get the events after it, oldest first, and has_more says whether to ask again.

POST /hooks

Subscribe a URL to events (REST hooks). The answer carries the signing secret.

DELETE /hooks/{id}

Unsubscribe. Answering a delivery with 410 Gone does the same.

Add a lead

curl https://api.capscout.ai/v1/api/leads \
  -H "Authorization: Bearer csk_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Habib Rahman",
    "email": "[email protected]",
    "phone": "904-555-0142",
    "message": "Looking for duplexes under $400k",
    "source_name": "Facebook Lead Ads"
  }'

Send at least one of name, email or phone. source_name is what your team sees as the lead's source. If the email already belongs to a client, the lead goes to the agent who works them.

Request bodies

Every field is optional unless it says otherwise.

POST /leads

name, email, phoneAt least one of the three.
messageWhat they asked. Kept on the lead; events and webhooks don’t carry it.
source_nameThe source your team sees on the lead. Defaults to the key’s name.

POST /contacts

emailHow an existing contact is found. A new one needs a name or an email.
name, phoneSet on create, and on update.
tagsA list of up to 30. An update adds to the tags already there.
stagenew, contacted, active, under_contract, closed or owner. Create only; defaults to active.
notesCreate only.
owner_emailA member of the team. Create only; defaults to the key’s member.
visibilityprivate, team or org. Create only; defaults to private.

POST /contacts/{id}/touches

kindcall, text, email, meeting or note. Required. A note sends no event.
directionoutbound (the default) or inbound.
summaryOne line, up to 255 characters.
bodyThe notes. They stay in CapScout.
occurred_atISO 8601. Defaults to now.
external_idYour id for it. The same one twice files once.

POST /contacts/{id}/stage

stagenew, contacted, active, under_contract, closed or owner. Required.

POST /hooks

urlA public https:// address. Required.
kindsA list of event names from Events below. Leave it out for all of them, including any added later.

A contact linked to your team’s connected CRM (today, Zoho CRM) takes its name and phone from there, so an update here skips those two fields.

Lists

GET /contacts takes limit (up to 100) and offset, and answers { "results": [...], "next_offset": 50 }. next_offset is null on the last page.

Events

Nine things can happen. Subscribe a webhook to any of them, or poll GET /events?kind=….

lead.createdA lead came in from a report, your form, an email, a portal or the API.
contact.createdSomeone was added to the book. A CSV import stays silent.
contact.stage_changedA contact moved to a new stage.
touch.loggedA call, text, email or meeting was logged.
report.sentA report was shared with a client.
report.viewedA client opened a report. Sent on the first open, then at most daily.
client.hotA client keeps coming back to their reports.
deal.stage_changedA deal moved on the pipeline.
matches.foundNew homes fit a client's buy box.

Every event has the same envelope, by webhook or by poll:

{
  "id": "evt_1842",
  "type": "report.viewed",
  "created_at": "2026-09-17T14:02:11.482913Z",
  "organization": { "id": 102 },
  "contact": {
    "id": 311,
    "name": "Grace Liu",
    "email": "[email protected]",
    "phone": "904-555-0188",
    "stage": "active",
    "tags": ["investor", "1031"],
    "owner_email": "[email protected]",
    "url": "https://app.capscout.ai/clients/311"
  },
  "data": {
    "home": {
      "property_id": "18-Fairfield-Ave-Jacksonville-FL-32206",
      "mode": "rental",
      "address": "18 Fairfield Ave, Jacksonville, FL 32206",
      "url": "https://app.capscout.ai/property/…/details?mode=rental"
    },
    "views": 3
  }
}

An event carries ids, names and links, plus the contact’s email, phone, stage, tags and owner’s email. The text of an email and the notes under a touch never leave CapScout. Only the one-line summary an agent types on a logged touch travels.

Webhooks

Add a URL in Settings → Integrations, or subscribe one with POST /hooks. It has to be a public https:// address. Answer with any 2xx within 10 seconds. Anything else is retried after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours, then dropped. A URL that accepts nothing for two days is paused and its Owners and Admins are told. Answer 410 Gone to unsubscribe.

Verify a delivery

Each delivery carries X-CapScout-Timestamp and X-CapScout-Signature. The signature is v1= plus the HMAC-SHA256 of the timestamp, a dot and the raw body, keyed with the endpoint's signing secret. X-CapScout-Delivery is unique per delivery, so you can drop a repeat.

import crypto from "node:crypto";

// rawBody is the request body exactly as received, before any JSON parsing.
export function isFromCapScout(secret, headers, rawBody) {
  const timestamp = headers["x-capscout-timestamp"];
  const expected = "v1=" + crypto
    .createHmac("sha256", secret)
    .update(timestamp + "." + rawBody)
    .digest("hex");
  const given = headers["x-capscout-signature"] ?? "";
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
  return fresh && given.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}
import hashlib, hmac, time

def is_from_capscout(secret: str, headers, raw_body: bytes) -> bool:
    timestamp = headers["X-CapScout-Timestamp"]
    signed = timestamp.encode() + b"." + raw_body
    expected = "v1=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    fresh = abs(time.time() - int(timestamp)) < 300
    return fresh and hmac.compare_digest(expected, headers.get("X-CapScout-Signature", ""))

Zapier, Make and n8n

CapScout on Zapier

The CapScout app on Zapier has a trigger for each of the nine events, the actions Create Lead, Create or Update Contact, Log Touch and Move Contact Stage, and a Find Contact search. You connect it with an API key. It is available by invitation for now: write to [email protected] and we’ll send you access.

Any tool, by webhook

No invitation and no code needed. In Zapier, add a Webhooks by Zapier → Catch Hook trigger, copy its URL, and add it as a webhook in CapScout. Pick the events you want and press Send a test so Zapier has a sample. For the other direction, use Webhooks by Zapier → POST with your key in the Authorization header to add a lead or log a touch. Make's Custom webhook and n8n's Webhook node work the same way.

Errors

Errors are JSON with a detail line written for a person. 401 means the key is missing, wrong or revoked. 403 means the team's plan has lapsed, or the key's member can see a contact but not change it. 404 means nothing with that id is visible to the key. 429 means slow down; the Retry-After header says for how long.

The API is additive: we add fields and endpoints, and we don't rename or remove them. Building something and need a field that isn't here? Write to [email protected].

CapScout

Real estate underwriting, done before the other offer lands.

Product
Features Pricing
Resources
Learn Calculators Compare tools Help FAQ Developers
Company
How it works For teams For property managers Contact
Legal
Privacy Terms Disclaimers For agents & teams Copyright / DMCA Accessibility
Featured on
  • CapScout — Featured on Startup Fame
  • CapScout — Featured on Fazier
  • CapScout — Verified on Dang.ai
  • CapScout — Featured on ToolPilot
  • Featured on launched.tools REVIEWED ✓
  • CapScout — Featured on LaunchKiwi
© 2026 CapScout. Analysis is informational, not financial or investment advice. Purpose-built for real estate underwriting.