Modules
Create and manage custom data structures with the Modules API
Modules are the building blocks of your Coherence workspace. Each module represents a type of data (Contacts, Deals, Projects, etc.) with its own schema, fields, views, and relationships.
Overview
Modules act as containers for your data. Each module has:
- Fields - Define the data structure (text, numbers, dates, references, etc.)
- Views - Display and interact with records (list, detail, kanban, calendar)
- References - Relationships to other modules
- Records - Individual data entries
Module Types
| Type | Description |
|---|---|
| Vendor | Built-in modules managed by Coherence (Contacts, Deals, etc.) |
| Template | Installed from the marketplace |
| Custom | Created by your workspace |
Endpoints Reference
Module Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /modules | List all modules |
| GET | /modules/:slug | Get module schema |
| POST | /modules | Create a module |
| PATCH | /modules/:moduleId | Update a module |
| DELETE | /modules/:moduleId | Delete a module |
Field Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /modules/:slug/fields | List module fields |
| POST | /modules/:moduleId/fields | Create a field |
| PATCH | /modules/:moduleId/fields/:fieldId | Update a field |
| DELETE | /modules/:moduleId/fields/:fieldId | Delete a field |
View Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /modules/:moduleId/views | List module views |
| POST | /modules/:moduleId/views | Create a view |
| PATCH | /modules/:moduleId/views/:viewId | Update a view |
| DELETE | /modules/:moduleId/views/:viewId | Delete a view |
Reference Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /modules/:slug/references | List module references |
| POST | /modules/:moduleId/references | Create a reference |
| PATCH | /modules/:moduleId/references/:referenceId | Update a reference |
| DELETE | /modules/:moduleId/references/:referenceId | Delete a reference |
List Modules
Retrieve all modules in your workspace.
GET /modules
Query Parameters
| Parameter | Type | Description |
|---|---|---|
visibility | string | Filter by visibility: active (default) or hidden |
Request
curl -X GET "https://api.getcoherence.io/v1/modules" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"modules": [
{
"moduleId": "mod_abc123",
"accountId": "acc_xyz789",
"name": "Contacts",
"singularName": "Contact",
"pluralName": "Contacts",
"slug": "contacts",
"icon": "users",
"status": "published",
"isCustom": false,
"vendorManaged": true,
"visibility": "active",
"origin": "vendor",
"displayField": {
"type": "concat",
"fields": ["first_name", "last_name"],
"separator": " "
},
"createdDateTime": "2024-01-15T10:30:00Z",
"updatedDateTime": "2024-01-20T14:45:00Z"
},
{
"moduleId": "mod_def456",
"accountId": "acc_xyz789",
"name": "Projects",
"singularName": "Project",
"pluralName": "Projects",
"slug": "projects",
"icon": "folder-kanban",
"status": "published",
"isCustom": true,
"vendorManaged": false,
"visibility": "active",
"origin": "custom",
"displayField": {
"type": "field",
"field": "name"
},
"createdDateTime": "2024-02-01T09:00:00Z",
"updatedDateTime": "2024-02-01T09:00:00Z"
}
]
}Get Module Schema
Retrieve detailed schema for a single module including fields, views, and references.
GET /modules/:slug
Request
curl -X GET "https://api.getcoherence.io/v1/modules/contacts" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"module": {
"moduleId": "mod_abc123",
"name": "Contacts",
"singularName": "Contact",
"pluralName": "Contacts",
"slug": "contacts",
"icon": "users",
"status": "published",
"isCustom": false,
"vendorManaged": true,
"visibility": "active",
"origin": "vendor",
"displayField": {
"type": "concat",
"fields": ["first_name", "last_name"],
"separator": " "
},
"quickCreateFields": ["first_name", "last_name", "email"],
"config": {},
"allowRecordActions": true,
"isDeletable": false,
"createdDateTime": "2024-01-15T10:30:00Z",
"updatedDateTime": "2024-01-20T14:45:00Z"
},
"fields": [
{
"fieldId": "fld_001",
"moduleId": "mod_abc123",
"name": "first_name",
"slug": "first_name",
"label": "First Name",
"dataType": "text",
"isRequired": true,
"isSystem": false,
"sortOrder": 1,
"config": {}
},
{
"fieldId": "fld_002",
"moduleId": "mod_abc123",
"name": "email",
"slug": "email",
"label": "Email",
"dataType": "email",
"isRequired": false,
"isSystem": false,
"sortOrder": 3,
"config": {
"multiValue": true
}
}
],
"views": [
{
"viewId": "view_001",
"moduleId": "mod_abc123",
"name": "All Contacts",
"viewType": "list",
"status": "published",
"sortOrder": 1,
"visibility": "account",
"config": {}
}
],
"references": [
{
"referenceId": "ref_001",
"slug": "account",
"sourceModuleId": "mod_abc123",
"targetModuleId": "mod_accounts",
"relationshipType": "many_to_one",
"targetType": "module",
"isRequired": false,
"cascadeDelete": false,
"cascadeUpdate": false
}
]
}Create Module
Create a new custom module.
POST /modules
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Internal name |
singularName | string | Yes | Display name for single record |
pluralName | string | Yes | Display name for multiple records |
slug | string | Yes | URL-friendly identifier (lowercase, hyphens only) |
icon | string | No | Icon name (defaults to puzzle) |
displayField | object | No | How to display record names |
quickCreateFields | array | No | Fields shown in quick create form |
config | object | No | Additional configuration |
Display Field Options
The displayField determines how records are displayed in lists and references.
Single Field:
{
"displayField": {
"type": "field",
"field": "name"
}
}Concatenated Fields:
{
"displayField": {
"type": "concat",
"fields": ["first_name", "last_name"],
"separator": " "
}
}Request
curl -X POST "https://api.getcoherence.io/v1/modules" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Projects",
"singularName": "Project",
"pluralName": "Projects",
"slug": "projects",
"icon": "folder-kanban",
"displayField": {
"type": "field",
"field": "name"
},
"quickCreateFields": ["name", "status", "owner"]
}'Response
{
"module": {
"moduleId": "mod_new123",
"accountId": "acc_xyz789",
"name": "Projects",
"singularName": "Project",
"pluralName": "Projects",
"slug": "projects",
"icon": "folder-kanban",
"status": "draft",
"isCustom": true,
"vendorManaged": false,
"visibility": "active",
"origin": "custom",
"displayField": {
"type": "field",
"field": "name"
},
"quickCreateFields": ["name", "status", "owner"],
"createdDateTime": "2024-02-15T10:30:00Z",
"updatedDateTime": "2024-02-15T10:30:00Z"
}
}After creating a module, add fields to define its data structure before creating records.
Update Module
Update an existing module's metadata.
PATCH /modules/:moduleId
Request Body
All fields are optional. Only include fields you want to update.
| Field | Type | Description |
|---|---|---|
name | string | Internal name |
singularName | string | Singular display name |
pluralName | string | Plural display name |
icon | string | Icon name |
displayField | object | Record display configuration |
quickCreateFields | array | Quick create form fields |
config | object | Additional configuration |
Request
curl -X PATCH "https://api.getcoherence.io/v1/modules/mod_new123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"icon": "briefcase",
"displayField": {
"type": "concat",
"fields": ["name", "client"],
"separator": " - "
}
}'Response
{
"module": {
"moduleId": "mod_new123",
"name": "Projects",
"singularName": "Project",
"pluralName": "Projects",
"slug": "projects",
"icon": "briefcase",
"displayField": {
"type": "concat",
"fields": ["name", "client"],
"separator": " - "
},
"updatedDateTime": "2024-02-16T08:00:00Z"
}
}Delete Module
Delete a custom module and all its records.
DELETE /modules/:moduleId
Deleting a module permanently removes all records. This action cannot be undone. Vendor-managed modules cannot be deleted but can be hidden.
Request
curl -X DELETE "https://api.getcoherence.io/v1/modules/mod_new123" \
-H "Authorization: Bearer YOUR_API_KEY"Response
HTTP 204 No Content
Hiding Modules
For vendor modules that cannot be deleted, use the hide endpoint:
curl -X POST "https://api.getcoherence.io/v1/modules/mod_abc123/hide" \
-H "Authorization: Bearer YOUR_API_KEY"To show a hidden module:
curl -X POST "https://api.getcoherence.io/v1/modules/mod_abc123/show" \
-H "Authorization: Bearer YOUR_API_KEY"Managing Fields
Fields define the data structure of a module.
Field Types
| Data Type | Description | Config Options |
|---|---|---|
text | Short text | maxLength |
long_text | Multi-line text | maxLength |
rich_text | Formatted text with HTML | toolbarPreset, attachments |
number | Numeric values | precision, min, max |
currency | Money values | currency, precision |
date | Date only | format |
datetime | Date and time | format, timezone |
email | Email addresses | multiValue |
phone | Phone numbers | multiValue |
url | Web addresses | - |
select | Single selection | options |
multi_select | Multiple selections | options |
checkbox | Boolean toggle | - |
user | User reference | multiValue |
reference | Module reference | See References section |
formula | Calculated field | expression, resultType |
rollup | Aggregated data | referenceSlug, field, aggregation |
auto_number | Auto-incrementing ID | prefix, padLength |
attachment | File uploads | maxFiles, allowedTypes |
Create Field
POST /modules/:moduleId/fields
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Internal name |
slug | string | Yes | URL-friendly identifier |
label | string | Yes | Display label |
dataType | string | Yes | Field type (see table above) |
isRequired | boolean | No | Whether field is required |
sortOrder | number | No | Display order |
config | object | No | Type-specific configuration |
privacyLevel | string | No | account, role, or private |
Example: Text Field
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/fields" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "project_name",
"slug": "project-name",
"label": "Project Name",
"dataType": "text",
"isRequired": true,
"sortOrder": 1,
"config": {
"maxLength": 200
}
}'Example: Select Field with Options
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/fields" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "status",
"slug": "status",
"label": "Status",
"dataType": "select",
"isRequired": true,
"config": {
"options": [
{ "slug": "planning", "label": "Planning", "color": "blue" },
{ "slug": "in-progress", "label": "In Progress", "color": "yellow" },
{ "slug": "completed", "label": "Completed", "color": "green" },
{ "slug": "on-hold", "label": "On Hold", "color": "gray" }
],
"defaultSlug": "planning"
}
}'Example: Formula Field
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/fields" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "total_value",
"slug": "total-value",
"label": "Total Value",
"dataType": "formula",
"config": {
"formula": {
"expression": "{quantity} * {unit_price}",
"resultType": "number"
}
}
}'Example: Auto-Number Field
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/fields" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "project_id",
"slug": "project-id",
"label": "Project ID",
"dataType": "auto_number",
"config": {
"prefix": "PRJ-",
"padLength": 4
}
}'This generates IDs like PRJ-0001, PRJ-0002, etc.
Update Field
PATCH /modules/:moduleId/fields/:fieldId
curl -X PATCH "https://api.getcoherence.io/v1/modules/mod_new123/fields/fld_001" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Full Name",
"isRequired": false
}'Delete Field
DELETE /modules/:moduleId/fields/:fieldId
curl -X DELETE "https://api.getcoherence.io/v1/modules/mod_new123/fields/fld_001" \
-H "Authorization: Bearer YOUR_API_KEY"Deleting a field removes all data stored in that field across all records. System fields cannot be deleted.
Managing Views
Views control how records are displayed and interacted with.
View Types
| Type | Description |
|---|---|
list | Table/grid view of records |
detail | Single record detail page |
form | Data entry form |
kanban | Card-based board view |
calendar | Calendar visualization |
Create View
POST /modules/:moduleId/views
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | View name |
viewType | string | Yes | View type (see table above) |
status | string | No | draft, published, archived |
visibility | string | No | account, team, private |
sortOrder | number | No | Display order in navigation |
config | object | No | View-specific configuration |
Example: List View
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/views" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Active Projects",
"viewType": "list",
"status": "published",
"visibility": "account",
"sortOrder": 1,
"config": {
"columns": ["name", "status", "owner", "due_date"],
"defaultSort": { "field": "due_date", "direction": "asc" }
}
}'Example: Kanban View
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/views" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Project Board",
"viewType": "kanban",
"status": "published",
"visibility": "account",
"config": {
"groupByField": "status",
"cardFields": ["name", "owner", "due_date"]
}
}'Update View
PATCH /modules/:moduleId/views/:viewId
curl -X PATCH "https://api.getcoherence.io/v1/modules/mod_new123/views/view_001" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "All Projects",
"config": {
"columns": ["name", "status", "owner", "due_date", "budget"]
}
}'Reorder Views
POST /modules/:moduleId/views/reorder
curl -X POST "https://api.getcoherence.io/v1/modules/mod_new123/views/reorder" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"views": [
{ "viewId": "view_001", "sortOrder": 1 },
{ "viewId": "view_002", "sortOrder": 2 },
{ "viewId": "view_003", "sortOrder": 3 }
]
}'Delete View
DELETE /modules/:moduleId/views/:viewId
curl -X DELETE "https://api.getcoherence.io/v1/modules/mod_new123/views/view_001" \
-H "Authorization: Bearer YOUR_API_KEY"Managing References
References define relationships between modules.
Relationship Types
| Type | Description |
|---|---|
one_to_one | Each record links to exactly one target |
one_to_many | One source record links to many targets |
many_to_one | Many source records link to one target |
many_to_many | Many-to-many relationship |
lookup | Read-only lookup to another module |
Target Types
| Type | Description |
|---|---|
module | Reference to another module's records |
user | Reference to workspace users |
Create Reference
POST /modules/:moduleId/references
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
slug | string | Yes | URL-friendly identifier |
targetModuleId | string | Conditional | Target module (required for module type) |
targetType | string | No | module (default) or user |
relationshipType | string | Yes | Relationship type |
isRequired | boolean | No | Whether reference is required |
cascadeDelete | boolean | No | Delete related records on delete |
cascadeUpdate | boolean | No | Update related records on update |
targetFilters | object | No | Filter target records |
config | object | No | Additional configuration |
Example: Many-to-One Reference
Link projects to accounts:
curl -X POST "https://api.getcoherence.io/v1/modules/mod_projects/references" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "account",
"targetModuleId": "mod_accounts",
"targetType": "module",
"relationshipType": "many_to_one",
"isRequired": true,
"cascadeDelete": false
}'Example: User Reference
Assign an owner to projects:
curl -X POST "https://api.getcoherence.io/v1/modules/mod_projects/references" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "owner",
"targetType": "user",
"relationshipType": "many_to_one",
"isRequired": false,
"targetFilters": {
"roleSlugs": ["admin", "project_manager"]
}
}'Example: Many-to-Many Reference
Link projects to tags:
curl -X POST "https://api.getcoherence.io/v1/modules/mod_projects/references" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "tags",
"targetModuleId": "mod_tags",
"targetType": "module",
"relationshipType": "many_to_many",
"isRequired": false
}'Update Reference
PATCH /modules/:moduleId/references/:referenceId
curl -X PATCH "https://api.getcoherence.io/v1/modules/mod_projects/references/ref_001" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"isRequired": true,
"cascadeDelete": true
}'Delete Reference
DELETE /modules/:moduleId/references/:referenceId
curl -X DELETE "https://api.getcoherence.io/v1/modules/mod_projects/references/ref_001" \
-H "Authorization: Bearer YOUR_API_KEY"Deleting a reference removes all relationship data between records. The target records themselves are not deleted unless cascadeDelete is enabled.
Error Responses
Common Errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid request body |
| 401 | unauthorized | Missing or invalid authentication |
| 403 | forbidden | Insufficient permissions |
| 404 | not_found | Module, field, view, or reference not found |
| 409 | conflict | Slug already exists |
| 422 | unprocessable_entity | Cannot process request |
Example Error Response
{
"error": {
"code": "validation_error",
"message": "Slug must contain only lowercase letters, numbers, and hyphens",
"details": {
"field": "slug"
}
}
}Related: API Overview | Authentication | Template System