Skip to main content
The Dench CRM is the shared database for agents and humans. Every list-shaped thing lives here, not in ad-hoc files.

Objects

Tables like people, company, task, or any custom object.

Fields

Typed columns: text, enum, relation, user, date, and more.

Entries

Rows, written one at a time or in batches up to 200.

Cells

Individual values, set, appended, or read per field.

Query

Filter, sort, paginate, search, and aggregate.

Statuses

Kanban columns with colors for any object.
people, company, and task are protected and cannot be deleted. Tasks are CRM entries on the task object, there is no separate dench tasks command.

Create an object

1

Inspect what exists

dench crm objects list --json
2

Create it with an icon

dench crm objects create lead --description "Sales leads" --default-view kanban --icon target --json
3

Add fields

dench crm fields create lead "Name" --type text --required
dench crm fields create lead "Email" --type email --indexed
dench crm fields create lead "Company" --type relation --related-object company --relationship many_to_one --indexed
dench crm fields create lead "Status" --type enum --enum-values '["New","Working","Qualified","Lost"]'
4

Optional: kanban statuses

dench crm statuses set lead --statuses '[{"name":"New","color":"#94a3b8"},{"name":"Qualified","color":"#22c55e"}]' --json

Field types

text, email, phone, url, number, boolean, date, file, tags.
dench crm fields create deal "Amount" --type number
dench crm fields create deal "Close Date" --type date
Field type is immutable. To change a field’s type, create a new field and migrate. dench crm fields update changes name, options, indexing, and enrichment, but not the type.

The protected Notes field

Every object ships a protected Notes (richtext) field for free-form prose, meeting notes, summaries, task details. It is hidden from list views and shown only when an entry is opened. Do not invent parallel Description/Summary columns, write Markdown to Notes.

Write data

dench crm entries create people --data '{"Name":"Ada Lovelace","Email":"ada@example.com"}' --json

Read data

dench crm query lead --where '{"Status":"Qualified"}' --sort '-Score' --limit 100 --json
Over the API, operator filters ($gt, $in, $contains, $and, $or) go in dslJson because the wire format rejects $-prefixed keys in nested objects. See the API playground.

Relation-first modeling

If a field name matches or aliases an existing object (Company, Client, Deal, Owner), use a relation (or user) field, not text.
Use entries create-many, entries update-many, cells set-many, or batch --file for three or more writes.