Custom Columns
Substring match on name, case-insensitive.
Tenant id (uuid v4)
Returned when the rate limit is exceeded
GET /api/v1/public/custom-columns HTTP/1.1
Host: api-stage.hesh.tech
x-api-key: YOUR_API_KEY
Accept: */*
{
"meta": {
"total": 1,
"lastPage": 1,
"currentPage": 1,
"perPage": 1,
"prev": 1,
"next": 1
},
"data": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"column_type": "text",
"is_required": true,
"status": "active",
"config": {
"min_chars": 1,
"max_chars": 1
},
"deleted_at": "2026-01-01T00:00:00.000Z"
}
]
}Creates a new custom column on a given module.
Notes
column_typeis immutable after creation.statuson create must beactiveorinactive. Use the delete endpoint to soft-delete.The per-module field limit is enforced; creation fails with 409 if reached.
config field — what to pass for each column_type
The config object is polymorphic: its required shape is determined by the sibling column_type value. The server validates the combination — sending a config that doesn't match the column type is rejected with 400.
text
{ "min_chars": 0, "max_chars": 500 }Both min_chars and max_chars are optional (nullable). Bounds are inclusive. null or omitted = no limit on that side. Constraints: min_chars >= 0, max_chars >= 1.
number
{ "number_type": "integer" }Required. Allowed values: "integer", "decimal". Controls the input widget and validation on stored values.
date_time
{ "time_type": "date_time" }Required. Allowed values: "date_time" (date + time), "date_only", "time_only".
people
Required. Allowed values: "user", "department", "position". Determines the kind of entity ids that people_options (and stored values) must reference. Immutable in practice — changing it invalidates existing options.
boolean
Both labels required and non-empty. Shown in the UI for the two states.
choice
Required. Allowed values: "single" (one choice per row) or "multi" (many). Use the choice_options array (see below) to define the options themselves.
Companion arrays
choice_options — required for choice columns on create; ignored for other column types. Must contain at least one entry of the form:
position is the display order (integer, >= 0). On update, use the nested management object instead:
people_options — only valid for people columns. On create, pass an array of entity uuids matching config.assignee_type (user / department / position ids). Empty or omitted = all active entities of that type are allowed:
On update, use the management object:
Note: remove takes people-option row ids (as returned by the get-by-id endpoint), not entity ids.
Concrete create-body examples
Tenant id (uuid v4)
Immutable after create.
Initial status. DELETED is not allowed on create.
falseType-specific config. Shape and required fields depend on column_type.
List of allowed entity IDs (user.id / department.id / position.id depending on config.assignee_type). Only valid when column_type = PEOPLE. Empty/omitted = all active entities of the chosen assignee_type are allowed. Ignored for other types.
Type-specific config. Shape depends on column_type.
Set when status = DELETED. Anchors the 30-day permanent deletion countdown.
Returned when the rate limit is exceeded
POST /api/v1/public/custom-columns HTTP/1.1
Host: api-stage.hesh.tech
x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 241
{
"module": "inventory",
"column_type": "text",
"name": "text",
"status": "active",
"is_required": false,
"config": {
"min_chars": 1,
"max_chars": 1
},
"choice_options": [
{
"label": "text",
"position": 1
}
],
"people_options": [
"123e4567-e89b-12d3-a456-426614174000"
]
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"column_type": "text",
"is_required": true,
"status": "active",
"config": {
"min_chars": 1,
"max_chars": 1
},
"deleted_at": "2026-01-01T00:00:00.000Z"
}Returns the full custom column record, including choice_options (for choice columns) and people_options resolved to display entities (for people columns).
Soft-deleted columns are returned (the response includes deleted_at and status = deleted).
Tenant id (uuid v4)
Stable slug used in API & integrations. Immutable after create.
Type-specific config. Shape depends on column_type.
Set when status = DELETED. Anchors the 30-day permanent deletion countdown.
Returned when the rate limit is exceeded
GET /api/v1/public/custom-columns/{id} HTTP/1.1
Host: api-stage.hesh.tech
x-api-key: YOUR_API_KEY
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"module": "inventory",
"name": "text",
"key": "text",
"column_type": "text",
"status": "active",
"is_required": true,
"config": {
"min_chars": 1,
"max_chars": 1
},
"choice_options": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"label": "text",
"position": 1
}
],
"people_options": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"entity_id": "123e4567-e89b-12d3-a456-426614174000",
"entity": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"first_name": "text",
"last_name": "text",
"avatar_id": "text"
}
}
],
"deleted_at": "2026-01-01T00:00:00.000Z"
}Updates a custom column. Any field not provided is left unchanged.
Notes
column_typemust match the persisted column type. Sending a different value is rejected with 400.Status transitions:
active↔inactivefreely.deletedsoft-deletes the column.Deleted columns cannot be edited — restore first.
config field — what to pass for each column_type
The config object is polymorphic: its required shape is determined by the sibling column_type value. The server validates the combination — sending a config that doesn't match the column type is rejected with 400.
text
{ "min_chars": 0, "max_chars": 500 }Both min_chars and max_chars are optional (nullable). Bounds are inclusive. null or omitted = no limit on that side. Constraints: min_chars >= 0, max_chars >= 1.
number
{ "number_type": "integer" }Required. Allowed values: "integer", "decimal". Controls the input widget and validation on stored values.
date_time
{ "time_type": "date_time" }Required. Allowed values: "date_time" (date + time), "date_only", "time_only".
people
Required. Allowed values: "user", "department", "position". Determines the kind of entity ids that people_options (and stored values) must reference. Immutable in practice — changing it invalidates existing options.
boolean
Both labels required and non-empty. Shown in the UI for the two states.
choice
Required. Allowed values: "single" (one choice per row) or "multi" (many). Use the choice_options array (see below) to define the options themselves.
Companion arrays
choice_options — required for choice columns on create; ignored for other column types. Must contain at least one entry of the form:
position is the display order (integer, >= 0). On update, use the nested management object instead:
people_options — only valid for people columns. On create, pass an array of entity uuids matching config.assignee_type (user / department / position ids). Empty or omitted = all active entities of that type are allowed:
On update, use the management object:
Note: remove takes people-option row ids (as returned by the get-by-id endpoint), not entity ids.
Concrete create-body examples
Tenant id (uuid v4)
Must match the column's persisted type. Sending a different value is rejected.
Type-specific config. Validated against column_type at the pipe stage.
ACTIVE ↔ INACTIVE freely; DELETED soft-deletes the column. Restoring a DELETED column uses the restore endpoint.
Type-specific config. Shape depends on column_type.
Set when status = DELETED. Anchors the 30-day permanent deletion countdown.
Returned when the rate limit is exceeded
PUT /api/v1/public/custom-columns/{id} HTTP/1.1
Host: api-stage.hesh.tech
x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 426
{
"column_type": "text",
"name": "text",
"is_required": true,
"config": {
"min_chars": 1,
"max_chars": 1
},
"status": "active",
"choice_options": {
"create": [
{
"label": "text",
"position": 1
}
],
"update": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"label": "text",
"position": 1
}
],
"remove": [
"123e4567-e89b-12d3-a456-426614174000"
]
},
"people_options": {
"create": [
"123e4567-e89b-12d3-a456-426614174000"
],
"remove": [
"123e4567-e89b-12d3-a456-426614174000"
]
}
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"column_type": "text",
"is_required": true,
"status": "active",
"config": {
"min_chars": 1,
"max_chars": 1
},
"deleted_at": "2026-01-01T00:00:00.000Z"
}Soft-deletes a custom column. Permanent deletion runs after 30 days.
Calling this endpoint sets status = deleted and stamps deleted_at. Use the restore endpoint to bring it back within the retention window.
Tenant id (uuid v4)
Message returned from API confirming the operation
The operation was done successfullyReturned when the rate limit is exceeded
DELETE /api/v1/public/custom-columns/{id} HTTP/1.1
Host: api-stage.hesh.tech
x-api-key: YOUR_API_KEY
Accept: */*
{
"message": "The operation was done successfully"
}Restores a soft-deleted custom column to status = active and clears deleted_at.
Fails with 409 if the per-module field limit is already reached — delete another column first.
Tenant id (uuid v4)
Message returned from API confirming the operation
The operation was done successfullyReturned when the rate limit is exceeded
POST /api/v1/public/custom-columns/{id}/restore HTTP/1.1
Host: api-stage.hesh.tech
x-api-key: YOUR_API_KEY
Accept: */*
{
"message": "The operation was done successfully"
}Last updated

