Project Records API
A project record is a structured details panel attached to one project: an instance of a published record form (for example “Enquiry details” on a sales pipeline). This API covers listing the record forms available in your organisation, attaching one to a project, reading and writing its values, moving a record to a newer form version, and the detach and restore lifecycle. Record forms themselves are authored in Runnit Studio; this API does not create or edit form definitions.
Authentication: every endpoint requires an API key. See API Keys & Authentication.
Record forms must be enabled for the organisation. Requests run inside the
organisation your key belongs to; a project or form outside it returns
404. Reads need organisation membership and follow the same client
visibility rules as project listings. Writes need project edit access
(project owner, project admin, or an organisation admin).
GET /api/v1/organizations/:id/record-forms
Section titled “GET /api/v1/organizations/:id/record-forms”The published record forms available for attaching, plus enabled so
integrations can tell when the organisation has switched record forms off.
Returns { enabled, recordForms: [{ id, name, slug, description, currentVersionId, templateKey, fields, updatedAt }], templates: [{ key, name, fields }] }. templateKey is "enquiry-details" or
"project-details" when the form was created from a starter template,
otherwise null. fields is a read-only preview (label, type,
required, help, options as option labels) of the form’s published
fields; templates carries the same preview shape for starter templates
that have not been created yet.
GET /api/v1/projects/:id/record
Section titled “GET /api/v1/projects/:id/record”The project’s attached record, or { "record": null, "restorable": true }
when a previously detached record could be restored. The record payload
contains one entry per field (fieldId, value, source of
record/project/computed, writable, mappedTo), a completeness
summary, recordRevision, version information (upToDate,
latestVersionId), and the pinned form definition, so a client can render
the record without further requests.
POST /api/v1/projects/:id/record
Section titled “POST /api/v1/projects/:id/record”Attach a published record form: body { "formId": "..." }. One active
record per project; attaching over an existing one returns 409.
PATCH /api/v1/projects/:id/record/values
Section titled “PATCH /api/v1/projects/:id/record/values”Write values by field id:
{ "values": { "fld_...": "New summary", "fld_...": 42000 }, "expectedRecordRevision": 3}Partial writes are fine; required fields affect completeness, not the
save. Every write carries expectedRecordRevision from your last read. A
stale revision returns 409 with code RECORD_REVISION_CONFLICT and the
canonical current record, so you can merge and retry. Invalid values return
400 with code RECORD_FIELDS_INVALID and per-field errors, and nothing is
written. Fields synced to project dates can return 409 with code
FIRM_MILESTONES_AFFECTED; retry with "confirmFirmMilestones": true after
confirming with a person.
POST /api/v1/projects/:id/record/upgrade
Section titled “POST /api/v1/projects/:id/record/upgrade”Move the record to the form’s latest published version: body
{ "expectedRecordRevision": 3, "migrations": { "fld_...": "value" } }.
New required fields must receive non-empty migration values; missing ones
return 409 with code RECORD_UPGRADE_REQUIRES_MIGRATIONS listing each
field with its label, type, and options. Values of fields removed from the
form are kept and returned in orphans.
DELETE /api/v1/projects/:id/record
Section titled “DELETE /api/v1/projects/:id/record”Soft-detach the record: body may include { "reason": "..." }. Values are
retained and restorable.
POST /api/v1/projects/:id/record/restore
Section titled “POST /api/v1/projects/:id/record/restore”Restore the most recently detached record with its values.
POST /api/v1/projects/:id/record/purge
Section titled “POST /api/v1/projects/:id/record/purge”Permanently delete a DETACHED record and its values. Organisation admins only.
GET /api/v1/organizations/:id/record-search?q=…
Section titled “GET /api/v1/organizations/:id/record-search?q=…”Project ids whose active record text values match the query (minimum two characters). Respects client visibility; values from fields no longer on the record’s form version never match.
GET /api/v1/organizations/:id/record-forms/:formId/export
Section titled “GET /api/v1/organizations/:id/record-forms/:formId/export”CSV of every active record of one form (report-export access required). One
row per project; columns are Label [fieldId] from the current published
version; option labels and calendar dates are formatted; financial columns
appear only with financial-report access.