Skip to main content
What is this? A concrete recipe for wiring an AI sales-development-rep (BDR) agent against Salty’s CRM. The agent researches prospects, logs outreach activity, and gets notified when leads change stage — all without humans clicking through dashboards.

The scenario

You’re a solopreneur running outbound. You have an LLM agent (Claude Desktop, Cursor, custom Python) that reads inbound leads from a form, enriches them, sends a personalized first-touch email, and tracks responses. You need a system of record for who you talked to, what about, what stage they’re in, and what to do next. Salty is that system of record. Your agent reads + writes via MCP or REST; signed webhooks notify your inbox or Slack when state changes.

What the agent does

StepToolSalty object touched
1. Inbound lead arrives(your form) → agent
2. Lookup or create companysearch_companiescreate_companycompany
3. Create the person, link to companycreate_person with primary_company_idperson
4. Add a deal in prospecting stagecreate_dealdeal
5. Send a first-touch email (via your provider)
6. Log the email send as an activitylog_activity (type: email_sent)activity
7. Move deal to awaiting_replyupdate_dealdeal
8. When the prospect replies, your inbound webhook → agent updates stage to engaged + logs activityupdate_deal + log_activitydeal, activity
9. If no reply in 5 days, your scheduler → agent logs follow-up activitylog_activityactivity

Driving it from Claude Desktop (MCP)

Once you’ve configured Claude Desktop with Salty MCP (instructions), you can drive the whole flow conversationally:
“A new lead came in: sarah@acme-corp.com. Search Salty for the company, create her, link them, and create a deal called ‘Acme Q3 expansion’ worth $40,000 in prospecting stage.”
Claude will:
  1. Call search_companies with {filter: {domain: "acme-corp.com"}}
  2. If no result, call create_company with name=Acme Corp, domain=acme-corp.com
  3. Call create_person with email, primary_company_id from step 2
  4. Call create_deal with name, value_cents: "4000000" (string-encoded bigint), stage: "prospecting", primary_company_id, primary_person_id
Four MCP tool calls. One conversational prompt. No browser tabs.

Driving it from your own backend (REST)

If your agent is a Python/Node service running 24/7:
import httpx

API = "$SALTY_API"  # e.g. https://api.trysalty.com/v1
H = {"Authorization": f"Bearer {SALTY_API_KEY}", "Content-Type": "application/json"}

# 1. Lookup or create company
r = httpx.get(f"{API}/companies?filter[domain]=acme-corp.com", headers=H).json()
company_id = r["data"][0]["id"] if r["data"] else httpx.post(
    f"{API}/companies", headers=H,
    json={"name": "Acme Corp", "domain": "acme-corp.com"}
).json()["id"]

# 2. Create person
person = httpx.post(f"{API}/people", headers=H, json={
    "email": "sarah@acme-corp.com",
    "first_name": "Sarah",
    "primary_company_id": company_id,
}).json()

# 3. Create deal
httpx.post(f"{API}/deals", headers=H, json={
    "name": "Acme Q3 expansion",
    "value_cents": "4000000",                  # string-encoded bigint
    "stage": "prospecting",
    "primary_company_id": company_id,
    "primary_person_id": person["id"],
})

React to deal state changes via webhooks

Register a webhook so your agent gets notified the moment a deal moves stage:
curl -X POST $SALTY_API/webhook-endpoints \
  -H "Authorization: Bearer $SALTY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-agent.com/salty-hook", "subscribed_events": ["deal.updated", "person.created"]}'
The response includes a whsec_… signing secret shown once — store it; future deliveries arrive with a Salty-Signature: t=<ms>,v1=<hex> header. Verify with HMAC-SHA-256 over <t>.<body>. See Webhooks.

Custom fields specific to your funnel

Extend the schema on the fly — no migrations, no service restarts:
curl -X POST $SALTY_API/schema/deal/attributes \
  -H "Authorization: Bearer $SALTY_API_KEY" \
  -d '{"attribute_key":"source","display_name":"Source","data_type":"enum",
       "enum_values":["typeform","linkedin","referral","cold_outbound"]}'
Now every deal write can include custom_attributes: {source: "linkedin"} — and bad values get rejected with a clear 400.

Volume guidance

A typical BDR agent doing 100 outbound + 200 follow-ups per month makes ~1,500 API calls (3-5 calls per touch). That puts you on Solo ($20/mo, 100k calls) — Free (500 calls/mo) is a demo tier and won’t sustain a real BDR workload, plus it blocks the custom attributes and webhooks the pattern above relies on. At 10× scale, Solo’s 100k cap still has plenty of headroom.
  • MCP server — connect Claude / Cursor / ChatGPT to Salty
  • Webhooks — signed delivery, retry, signing-secret rotation
  • Schema engine — what validation does and doesn’t enforce
  • Custom Objects — when “deal” isn’t the right shape for your pipeline