Agent Native CRM

GET/v1/schema

Six primitives

Every workspace has these, they are all extendable, and none of them can be removed. Read the schema before you guess a field name — it tells you every object, field, stage and saved view this workspace has.

Records

Goodbye duplicates, hello natural keys.

Activities

Append-only, and never rewritten.

Tasks

Claim it, or be told you lost.

Deals

Stages that are events, not a column.

Schema registry

Your fields, ready to extend.

Views

Saved queries the dashboard renders from.

What the service layer guarantees

These are behaviours, not settings. Each one is enforced in the services and covered by a test, which is why an agent can rely on it without asking a human how this particular workspace was configured — and why it holds identically over REST and through the MCP server, because both are the same operation.

01

Upsert, never duplicate

POST /v1/companies matches on the domain, /v1/people on the email or the LinkedIn URL. Existing gives you 200 and created: false; new gives you 201. Only the keys you send are written.

02

Unknown fields are rejected

Not silently dropped. The error lists the fields that do exist, so a wrong guess costs one round trip rather than a day of writes going nowhere.

03

Contact safety is enforced, not advised

A record marked do_not_contact cannot be linked to a new task on an outreach channel. The API answers 409 do_not_contact.

04

Claiming is atomic

One conditional update inside the workspace’s Durable Object. Two agents can race and exactly one wins; the other gets 409 already_claimed.

05

Nothing is deleted

There is no DELETE route on a record. Schema elements soft-hide and purge after thirty days; standard fields hide but never drop.

06

Every change writes its own diff

Registry edits emit schema_changed with the diff attached, attributed to whoever made them — agent or human, through the same API.

GET/v1/people

Lists are queries, not folders

A list holds members with a status and a reason from the registry, so “why is this person in the Q3 list and marked rejected” is a question the data answers rather than one you ask in Slack.

POST/v1/tasks

Seven channels, and a chain

A task names the channel the work happens on. Closing one can create its follow-up through parent_task_id, which is how sequencing happens here — chained tasks rather than a rules engine nobody can read.

  • email
  • linkedin
  • whatsapp
  • call
  • review
  • research
  • other

More time to build

One skill file, one OpenAPI document, one MCP server generated from it. No SDK to learn and no tool logic written by hand.