Every client portal, documented and comparable.
Setting up a client portal is a checklist and a person clicking through it, rebuilt for every client. Kalup turns each portal into files you can read, document and compare. Keep one repo per client.
From an existing portal to a documented one.
Start from what the client already has. Nothing here writes to a portal.
- 01
Pull the client portal into files
0.2$ kalup pullBrings the objects, groups and properties of an existing portal into config. Nothing to write by hand. - 02
Write the data dictionary
0.2$ kalup docsA Markdown data dictionary generated from the files, so the documentation is never older than your files. - 03
See what has not been promoted
0.2$ kalup compare sandbox productionShows what a colleague built in the sandbox and has not moved to production yet, edits included. - 04
Know what changed since last time
0.2$ kalup snapshot --target productionSaves a scoped observation of the configuration, with what could not be read listed. Compare against it later to see what changed in the portal since. - 05
Reuse a setup across clients
0.2$ kalup add ../blueprints/renewals-1.0.0.jsonBlueprints: a versioned setup you add to each client repo. kalup blueprint upgrade merges a new version into each and keeps the client's own changes. No portal changes until someone plans and applies.
What your colleague built, and never moved.
Compare takes two sides, each a target, a snapshot file or your config, and lists the differences in the same shape as a plan.
$ kalup compare sandbox production a: target sandbox, portal 1111111 b: target production, portal 2222222 3 equal, 1 differ, 1 only in a, 0 only in b, 0 unmanaged, 0 unknown, 0 excluded differs: property:companies/billing_status add options[PAST DUE]: null -> {"value":"PAST DUE","label":"Past due","hidden":false,"description":""} only in a: property:companies/renewal_date $
<!-- an excerpt of kalup docs output -->
# acme\-crm data dictionary
Source: the config files.
## companies
### Properties
| Internal name | Key | Label | Type | Field type | Group | Managed or reference | Codec | Required | Description |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| billing\_status | billingStatus | Billing status | enumeration | select | billing | managed | enum | no | |
| renewal\_date | renewalDate | Renewal date | date | date | billing | managed | date | no | |acme-crm/ one repo per client kalup.config.ts targets: sandbox 1111111, production 2222222 kalup/objects/ companies.ts, deals.ts, subscription.ts .kalup/snapshots/ production/20260901T090000000Z.json
What Kalup does not do for you.
Knowing where it stops is part of trusting what it does.
- It does not move records.
Setting up a portal moves configuration only. Contacts, companies and deals stay where they are.
- A snapshot is not a backup.
A snapshot is a scoped observation of the configuration, with what could not be read listed. It holds no record values, and nothing restores from it.
- It does not click through the UI for you.
Record page layouts, saved views and conditional property logic have no public API. The plan says so, and a person makes those changes. Printed steps for them come later.
Start with one portal.
kalup init pins a target, writes the files and runs the first pull. Nothing is written to the portal.