Acquisitions TeamRH
Shared demo. Sample data resets on its own, nothing is sent to sellers, and no real keys are connected.

Settings

Team, pipeline, tags, branding, integrations, enrichment, and the audit log.

Provider keys live only in environment variables. Set them in .env.local for development and in the hosting provider for production, then restart. Provider credentials are never stored in the database.
Database
Local PGlite file under .pglite (demo data, single machine)
DATABASE_URL
pglite
Auth
Signed in through DEV_AUTH_EMAIL. Remove before deploying.
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY
supabase
Property data
Deterministic sample data
PROPERTY_DATA_PROVIDER=realestateapi, REALESTATEAPI_KEY
mock
SMS
Messages are recorded, nothing is sent
MESSAGING_PROVIDER=twilio, TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN or TWILIO_API_KEY_SID and TWILIO_API_KEY_SECRET, TWILIO_FROM_NUMBER or TWILIO_MESSAGING_SERVICE_SID
mock
Email
Emails are recorded, nothing is sent
EMAIL_PROVIDER=resend, RESEND_API_KEY, EMAIL_FROM
mock
Judgment (Jev)
Keyword rules, low confidence, never acts automatically
JUDGMENT_PROVIDER=typesafe, TYPESAFE_API_KEY
mock
Sequences
Use Send due steps now on the Campaigns page until a scheduler is set
CRON_SECRET plus a scheduler hitting /api/cron/dispatch every minute
manual

API keys

Other software uses a key to send leads to this workspace. Each tool should get its own key so it can be revoked on its own.

No keys yet.

Webhooks

When something happens in the CRM, a signed JSON POST goes to each URL below. Deliveries time out after 5 seconds and an endpoint pauses itself after 10 failures in a row.

No webhooks yet.

Add webhook
Events

Checking every event, or none, subscribes the endpoint to all events, including ones added later.

Import and export

CSV files up to 2 MB and 2,000 rows. Columns are matched by header name, in any order.

Import leads
Download template

Required: address, city, state, zip. Optional: first_name, last_name or name, phone, email, asking_price, source, urgency, beds, baths, sqft, year_built, property_type, notes, external_id. A row that matches an open lead at the same address adds a note to that lead. SMS consent is always set to unknown.

Import buyers
Download template

Required: first_name, name, or company. Optional: last_name, phone, email, website, states (two letter codes separated by commas or spaces, for example MD, PA), source, notes. A row is skipped when its email or phone already belongs to a buyer. A row with no phone and no email is skipped when a buyer with the same company and first name exists. A buyers export can be imported as it is.

Export

Cells that begin with =, +, -, or @ are prefixed with a single quote so a spreadsheet does not run them as formulas.

Connect other software

Anything that can send or receive an HTTP request can connect: Zapier, Make, a website form, a dialer, a list provider, or a script.

1. Send leads in

Create an API key above, then POST JSON to https://wholesale-demo-six.vercel.app/api/v1/leads. Send one lead, or { "leads": [...] } with up to 200. Field names may be camelCase or snake_case. JSON is expected; form encoded and multipart form posts work for a single lead. Required: address, city, state, zip. Notes may be up to 5,000 characters. A lead at an address that already has an open lead is not created twice; a note is added instead and the response marks it as a duplicate. The limit is 120 requests per minute per key.

curl -X POST https://wholesale-demo-six.vercel.app/api/v1/leads \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address":"123 Main St","city":"Baltimore","state":"MD","zip":"21201","name":"Jane Doe","phone":"410-555-0100","asking_price":150000,"source":"Website form"}'

Check that a key works:

curl https://wholesale-demo-six.vercel.app/api/v1/ping -H "Authorization: Bearer YOUR_API_KEY"

Read leads back, newest first, for polling triggers:

curl "https://wholesale-demo-six.vercel.app/api/v1/leads?updatedSince=2026-01-01T00:00:00Z&limit=100" -H "X-Api-Key: YOUR_API_KEY"

2. Send events out

Add a webhook above. Each delivery is a JSON POST with the shape { id, event, createdAt, orgId, data } and the headers X-DealCalc-Event, X-DealCalc-Delivery, X-DealCalc-Timestamp, and X-DealCalc-Signature. The body id names the event and is the same at every endpoint that receives it, so use it to ignore an event you have already handled. X-DealCalc-Delivery is different for every delivery attempt and matches one row in the delivery list above. Reply with any 2xx status within 5 seconds. Failed deliveries are not retried, so poll the leads endpoint if you need a backstop.

3. Verify the signature

The signature is sha256= plus the hex HMAC-SHA256 of {timestamp}.{raw body} using the endpoint signing secret. Reject requests older than 5 minutes. Node example:

const crypto = require("node:crypto");

// rawBody must be the exact bytes received, before any JSON parsing.
function verifyDealCalcWebhook(headers, rawBody, secret) {
  const timestamp = headers["x-dealcalc-timestamp"];
  const given = String(headers["x-dealcalc-signature"] || "").replace("sha256=", "");
  const expected = crypto.createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300; // 5 minutes
  const a = Buffer.from(expected);
  const b = Buffer.from(given);
  return fresh && a.length === b.length && crypto.timingSafeEqual(a, b);
}

4. Zapier and Make

  • Into the CRM (Zapier): add the action Webhooks by Zapier, event POST. URL https://wholesale-demo-six.vercel.app/api/v1/leads, payload type json, map your fields under Data, and add the header Authorization with the value Bearer YOUR_API_KEY.
  • Out of the CRM (Zapier): start a Zap with the trigger Webhooks by Zapier, event Catch Hook. Copy the hook URL Zapier gives you, paste it above as a new webhook, pick the events, then press Send test so Zapier sees a sample.
  • Make: use the HTTP module, Make a request, for inbound leads with the same URL and header. For outbound, create a Custom webhook in Make and paste its URL above as a webhook.
  • Polling instead of webhooks: Webhooks by Zapier, event Retrieve Poll, URL https://wholesale-demo-six.vercel.app/api/v1/leads, key leads, with the X-Api-Key header. Zapier removes duplicates by the id field.
  • Spreadsheets: use the CSV import and export above. No key is needed.

The full reference, including every event payload, is in docs/INTEGRATIONS.md under Connecting other software.