Skip to main content
Every curl example below uses $SALTY_API as the base URL — set it once and the snippets work as-is.
export SALTY_API=https://api.trysalty.com/v1
All requests require Authorization: Bearer <token> (an sk_live_… API key, a Supabase JWT, or a salty_oat_… OAuth token). See Authentication.

Conventions

  • Identifiers are UUIDs unless noted.
  • Timestamps are ISO 8601 strings (2026-05-24T02:45:46.461Z).
  • bigint fields (deals.value_cents) are returned as strings to avoid JS precision loss.
  • All errors use the Stripe-shaped envelope. See Errors.
  • Pagination uses opaque cursors. See Pagination.
  • POST is idempotent when you pass Idempotency-Key. See Idempotency.
  • Rate limits are per workspace, per plan tier. See Rate limits.
  • Custom attributes are validated by the schema engine. See Schema engine.

Interactive explorer

Every endpoint listed here is also available in the Scalar API explorer at $SALTY_API/reference. Paste your key, click an endpoint, send a request, see the real response.

Endpoints in v1

GroupEndpoints
WorkspaceGET /workspace, GET /workspace/usage, PATCH /workspace
API keysGET /api-keys, POST /api-keys, DELETE /api-keys/:id
PeopleCRUD + POST /people/search + ?expand=primary_company
CompaniesCRUD
DealsCRUD + ?expand=primary_company,primary_person
NotesCRUD (parent must be person/company/deal)
TasksCRUD (parent optional)
ActivitiesCRUD (parent + occurred_at required)
SchemaDeclare/modify/deprecate attribute definitions
Custom ObjectsDefine new object types + records

SDK alternative

Every endpoint here is also a method on the Salty class:
import { Salty } from '@salty/sdk';
const salty = new Salty({ apiKey: process.env.SALTY_API_KEY! });

await salty.people.postPeople({ body: { email: 'jane@acme.com' } });
await salty.schema.getSchemaByObjectType({ path: { object_type: 'person' } });