Skip to main content

Saving data

Endpoint: POST /api/tickets/multi

Create, update, and delete records in a single batch request. The endpoint accepts an array of operations.

Permissions

All write operations respect the authenticated user's permissions. The API returns an error if the user is not authorized to perform the requested action on the target record or app.

Creating records

Send an array with one or more record objects. Each object must include:

  • transition: "add" - the create action
  • app_alias - app type (e.g., "TASK", "TICKET")
  • workspace_alias - target workspace (e.g., "IT")
  • Field values keyed by field name
curl --request POST \
--url "https://acme.comind.work/api/tickets/multi" \
--header "Authorization: CMW_AUTH_CODE YOUR-TOKEN" \
--header "Content-Type: application/json" \
--data '[{
"transition": "add",
"app_alias": "TASK",
"workspace_alias": "HELPDESK",
"title": "New task via API",
"priority": "high",
"description": "<!-- html --><p>Task description here</p>"
}]'

Response

[
{
"successful": true,
"created": true,
"data": {
"id": "new-record-guid",
"number": 456,
"project_alias": "HELPDESK",
"publishing_alias": "TASK"
},
"warnings": []
}
]

Rich text fields

Prefix HTML content with <!-- html --> to indicate it should be stored as rich text:

{
"description": "<!-- html --><p>This is <strong>formatted</strong> text</p>"
}

Plain text and markdown are also accepted - the server converts them to HTML automatically. The <!-- html --> prefix tells the API the content is already HTML and should not be converted.

Markdown conversion supports **bold**, *italic*, [link](url), and paragraph breaks (double newlines).

Lookup values

Lookup fields (state, priority, custom dropdowns) require internal db values, not display captions. Use GET /api/schema/{WS}!{APP} to discover available lookup values:

{ "priority": "high" }
{ "state": "open" }

Updating records

Provide the record id and a transition (action alias):

curl --request POST \
--url "https://acme.comind.work/api/tickets/multi" \
--header "Authorization: CMW_AUTH_CODE YOUR-TOKEN" \
--header "Content-Type: application/json" \
--data '[{
"id": "record-guid",
"transition": "edit",
"title": "Updated title",
"priority": "high",
"comment": "<!-- html --><p>Changed priority</p>"
}]'

Only include fields you want to change. Omitted fields are not modified.

Available transitions

Use the schema endpoint to discover which actions are available for an app:

GET /api/schema/{workspace}!{app}

The transitions array in the response lists available actions with their aliases:

Common aliasPurpose
editGeneral edit (most apps)
addCreate a new record
deleteDelete the record
App-specificCustom actions like approve, reject, close, assign

Adding a comment

Include the comment field to add a comment alongside the update:

{
"id": "record-guid",
"transition": "edit",
"comment": "<!-- html --><p>Updating per client request</p>",
"minor_change": false
}

Set minor_change: true to suppress notifications for the update.

Deleting records

curl --request POST \
--url "https://acme.comind.work/api/tickets/multi" \
--header "Authorization: CMW_AUTH_CODE YOUR-TOKEN" \
--header "Content-Type: application/json" \
--data '[{"id": "record-guid", "transition": "delete"}]'

Batch operations

The endpoint accepts an array, so you can create, update, and delete multiple records in a single request:

[
{ "transition": "add", "app_alias": "TASK", "workspace_alias": "IT", "title": "Task 1" },
{ "transition": "add", "app_alias": "TASK", "workspace_alias": "IT", "title": "Task 2" },
{ "id": "existing-guid", "transition": "edit", "priority": "high" },
{ "id": "old-guid", "transition": "delete" }
]

The response is an array with one result per operation, in the same order.

Field names and values

The API expects internal (db) field names and values:

WhatFormatExample
Field namedb namekeeper_id, c_priority, state
Lookup valuedb value"high", "open", "approved"
Person fielduser GUID"a1b2c3d4-..."
Link fieldrecord GUID"e5f6g7h8-..."

Use GET /api/schema/{WS}!{APP} to discover field names and lookup values for your target app.

tip

The MCP tools layer adds automatic resolution on top of the raw API - it accepts field captions instead of db names, lookup display values (case-insensitive), person names instead of GUIDs, and record slugs ("IT/TASK123") instead of GUIDs. If you're working through MCP, these conveniences are available automatically.

TypeScript SDK example

Load deals over $1000, double the price, and save:

async function doubleBigDeals() {
const deals = await comind.records.retrieve(
"w/CRM/a/DEAL/tickets/list",
{ limitRecords: 1000, listOfFields: "id,title,c_amount", rlx: "c_amount>1000" }
);

for (const deal of deals) {
deal.c_amount = deal.c_amount * 2;
deal.transition = "edit";
}

await comind.records.save(deals);
console.log(`Updated ${deals.length} deals`);
}