> ## Documentation Index
> Fetch the complete documentation index at: https://trysalty.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# FAQ

> Frequently asked questions about Salty — the developer-first CRM for AI agents. How it compares to HubSpot/Attio, pricing, exports, self-hosting, rate limits, and more.

> **Salty** is a developer-first CRM (Customer Relationship Management) built for AI agents. This FAQ answers the questions solopreneurs and developers ask most often when evaluating Salty.

## What is Salty?

Salty is a developer-first CRM built for AI agents. It exposes a clean REST API, a Model Context Protocol (MCP) server, a CLI, and signed webhooks — **no dashboards, no integration marketplace**. Your AI agent does the work; Salty is the database underneath.

See [Introduction](/docs/introduction) for the full pitch and [Use cases → AI Sales BDR](/docs/use-cases/sales-bdr) for a concrete agent recipe.

## How is Salty different from HubSpot, Attio, or Salesforce?

|                | Traditional CRMs                           | Salty                              |
| -------------- | ------------------------------------------ | ---------------------------------- |
| Built for      | Humans first                               | AI agents first                    |
| Interface      | Dashboards, forms, integration marketplace | REST + MCP + CLI + signed webhooks |
| Pricing        | Per seat                                   | Per API call                       |
| Schema changes | Plan, migrate, ship                        | `add_attribute`, write — runtime   |
| Integrations   | Their marketplace                          | Your agent calls them directly     |
| MCP support    | Bolted on (or absent)                      | First-class — 15 tools, OAuth 2.1  |
| Admin UI       | The product                                | A thin inspection layer            |

## Can humans also use Salty, or is it agent-only?

Salty ships with a **thin admin UI** at:

* `/api` — manage API keys
* `/records/{people,companies,deals}` — browse and inspect data with full detail views
* `/pricing` — plan + usage + upgrade/cancel
* `/status` — health of every service

It's intentionally minimal. Most workflow happens through the agent. Humans use the admin UI for inspection, key management, billing, and emergency edits.

## What counts as an API call for billing purposes?

Every authenticated request to the REST API counts as **one call**. **MCP tool invocations forward to the REST API**, so each MCP tool call is one API call. Admin UI actions authenticated via JWT (billing, key management, workspace settings) are **exempt** — your workspace can never be locked out of its own settings by hitting the cap.

| Plan | API calls / month | Records |
| ---- | ----------------- | ------- |
| Free | 500               | 10      |
| Solo | 100,000           | 25,000  |
| Pro  | 1,000,000         | 250,000 |

Free is **experience-only** — it lets you demo the platform via REST/MCP/CLI but blocks schema extension, webhooks, and a second active API key. Workspace auto-pauses after 30 days idle. See [Concepts → Billing](/docs/concepts/billing).

Overage on paid plans: `$1` per 10,000 calls beyond cap, `$0.50` per 1,000 records beyond cap.

## Can I export my data?

Yes — in one click. `GET /workspace/export` returns a single JSON document of your whole workspace (people, companies, deals, notes, tasks, activities, custom objects, and schema):

```bash theme={null}
curl $SALTY_API/workspace/export \
  -H "Authorization: Bearer $SALTY_API_KEY" > workspace.json
```

The per-object paginated list endpoints still exist too, if you'd rather pull one type at a time:

```bash theme={null}
curl -G $SALTY_API/people --data-urlencode "limit=500" \
  -H "Authorization: Bearer $SALTY_API_KEY" > people.json
```

And you can delete your whole workspace yourself anytime — no vendor lock-in.

## Can I self-host Salty?

Self-hosting is planned for **v1.1**. The entire stack is Hono + Next.js + Drizzle on Postgres with Supabase Auth — deployable to any Node host. v1 launches as a hosted service to keep the support surface contained while the product stabilizes.

## What happens when I hit my plan's API cap?

Agent traffic (`sk_live_…` API keys and `salty_oat_…` OAuth tokens) returns **HTTP 429** with code `cap_exceeded` until either:

1. The start of the next calendar month (counter rolls over lazily on first call), **or**
2. You raise `hard_cap_api_calls` in workspace settings, **or**
3. You upgrade your plan.

Admin traffic via Supabase JWT is **exempt** — you can always reach `/billing` to upgrade or set a higher cap. The counter resets lazily, no cron, no surprise re-enable.

## Can multiple AI agents share a single Salty workspace?

Yes. Create one API key per agent:

```bash theme={null}
salty keys create --name "sales-bdr-prod"
salty keys create --name "customer-success-bot"
```

Every request is logged in `api_call_log` with which key made it. MCP supports OAuth too — each MCP client (Claude Desktop instance, Cursor, custom agent) gets its own access token via dynamic client registration.

## Does Salty charge per record or per call?

**Both, as soft caps with overage**. Each plan includes both a call allowance and a record allowance (table above). Overage: `$1` per 10,000 calls beyond cap, `$0.50` per 1,000 records over cap.

You can also set a **hard cap** per workspace to prevent overage entirely — calls just `429` once the hard cap is hit instead of charging you for the surplus.

## How reliable are Salty webhooks?

Every webhook delivery is **HMAC-SHA-256 signed** (`Salty-Signature: t=<ms>,v1=<hex>`). Retries follow a `1s → 5s → 30s → 5min → 30min → 2h → 12h` exponential backoff. After **8 failed attempts** the endpoint is automatically deactivated and a `webhook_endpoint.failed` meta-event fans out to any other still-active endpoints in the workspace — so you can be notified of your own broken receiver via a different webhook.

The delivery worker uses Postgres `FOR UPDATE SKIP LOCKED` for safe horizontal scaling. See [Webhooks](/docs/webhooks/introduction).

## Can I extend Salty's data model?

Yes — **two mechanisms**:

1. **`add_attribute`** on any native object (person, company, deal, note, task, activity). Supports `text`, `number`, `boolean`, `date`, `datetime`, `enum`, `reference`, `json`. Values land in `custom_attributes`.
2. **Custom objects** — define entirely new object types like `invoices` or `projects` with their own attributes and records.

Both work at runtime — no migrations, no service restarts. See [Schema engine](/docs/concepts/schema-engine).

## What's Salty's rate limit?

| Plan | Sustained     | Burst         |
| ---- | ------------- | ------------- |
| Free | 2 req/sec     | 10 req/sec    |
| Solo | 100 req/sec   | 500 req/sec   |
| Pro  | 1,000 req/sec | 5,000 req/sec |

Enforced via a Postgres token-bucket (`consume_rate_limit` PL/pgSQL function). Every response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` headers. On 429 the response includes `Retry-After` (seconds). No Redis dependency.

## Does Salty support webhooks for every object?

Yes. Every native CRUD operation fires an event:

* `person.created`, `person.updated`, `person.deleted`
* `company.*`, `deal.*`, `note.*`, `task.*`, `activity.*`
* `custom_object_record.*`
* `schema.attribute_added`, `schema.attribute_modified`, `schema.attribute_deprecated`
* `webhook_endpoint.failed` (meta-event when an endpoint deactivates)

Subscribe to all events with `subscribed_events: ["*"]` or pass specific event names. No glob patterns in v1.

## What MCP clients work with Salty?

Any MCP client supporting the **Streamable HTTP transport with OAuth 2.1**:

* **Claude Desktop** — drop the config snippet in `~/Library/Application Support/Claude/claude_desktop_config.json` (see [MCP introduction](/docs/mcp/introduction))
* **Cursor** — native MCP support
* **ChatGPT** — when MCP support lands publicly
* **Custom clients** built on `@modelcontextprotocol/sdk`

For stdio-only clients (Claude Desktop, Cursor), use **`mcp-remote`** as a stdio↔HTTP bridge. By default it runs the full OAuth dance and caches the token in `~/.mcp-auth`; pass `--header "Authorization:Bearer sk_live_…"` to skip OAuth and authenticate with a long-lived [API key](/docs/concepts/authentication#1-api-keys-sk_live_…) instead. See [MCP introduction → Adding Salty to Claude Desktop / Cursor](/docs/mcp/introduction#adding-salty-to-claude-desktop-/-cursor) for both config snippets. The MCP server returns server-level `instructions` on `initialize` so connected agents know Salty's 15 tools and conventions without exploring — see the [Agent guide](/docs/mcp/agent-guide).

## Is Salty open source?

v1 ships as a hosted product. The **TypeScript SDK** (`@salty/sdk`) and **CLI** ([`salty-cli`](https://www.npmjs.com/package/salty-cli)) are **MIT-licensed** and open on npm; the core API, admin UI, and MCP server are closed-source for now. The `AGENTS.md` operating manual that documents Salty's MCP tool surface is public, so any agent can learn how to drive the API.

## Can an AI agent delete all my data?

No. Record deletes go to a **30-day trash** you can restore from — there is no hard-delete tool exposed to agents. And you can hand an agent a **read-only key** (`read_only: true`) that can't write at all. See [Authentication](/docs/concepts/authentication#1-api-keys-sk_live_…).

## Can I sign up with any email address?

Almost. Gmail, Outlook, Yahoo, iCloud, and Proton all work — you don't need a company domain.

What doesn't work: **disposable and temporary mailboxes** (Mailinator, Guerrilla Mail, 10 Minute Mail, and \~121k other burner domains, including wildcard subdomains), plus domains that can't receive mail at all — `example.com` and the reserved TLDs `.test`, `.example`, `.invalid`, `.localhost`, `.local`. Free-tier abuse from throwaway addresses is the reason; a workspace is tied to an address we can actually reach for verification, billing, and cap warnings.

Existing workspaces are never affected by later additions to that list. If a legitimate domain gets rejected, email support and we'll allowlist it. Programmatically the rejection surfaces as `403 email_domain_not_allowed` — see [Authentication](/docs/concepts/authentication#accepted-signup-emails).

## Where is my data stored?

Production data lives in a managed Postgres database. Supabase handles auth — email/password (10+ character policy), passwordless **passkeys**, and optional **TOTP two-factor**; Google/GitHub OAuth is coming soon. All traffic is HTTPS. Data residency options will be available at v1.1.

## What's Salty's SLA?

v1 doesn't ship with a contractual SLA. The status page at `/status` polls every 30 seconds and shows real uptime; we recommend that as the source of truth while v1 stabilizes. A contractual SLA (99.9% target) is part of the v1.1 plan once we've accumulated enough production runtime data to commit honestly.

## Still have questions?

* [Quickstart](/docs/quickstart) — 60 seconds, one prompt, your first record
* [Use cases](/docs/use-cases/sales-bdr) — concrete agent workflows
* [REST vs MCP vs CLI](/docs/concepts/surfaces) — which one to call when
* [Concepts](/docs/concepts/authentication) — deep-dive on each surface
