# Retrieving data

## Listing records[​](#listing-records "Direct link to Listing records")

**Endpoint:** `POST /api/w/{workspace}/a/{app}/tickets/list`

Omit the `/w/{workspace}/a/{app}` prefix to query across all workspaces and apps the user has access to.

### Request body[​](#request-body "Direct link to Request body")

```
{
  "limitRecords": 10,
  "skipRecords": 0,
  "sortBy": "update_date desc",
  "rlx": "state=\"open\"",
  "listOfFields": "ALL",
  "loadRichTexts": true,
  "expandRecord": false,
  "skipAncestors": true
}
```

| Parameter       | Type    | Description                                                                      |
| --------------- | ------- | -------------------------------------------------------------------------------- |
| `limitRecords`  | number  | Max records to return (default: 10)                                              |
| `skipRecords`   | number  | Offset for pagination (default: 0)                                               |
| `sortBy`        | string  | Sort field and direction, e.g. `"creation_date desc"`                            |
| `rlx`           | string  | Filter expression (see [Filter syntax](#filter-syntax-rlx) below)                |
| `listOfFields`  | string  | `"ALL"` for all fields, `"GRID"` for list fields, or comma-separated field names |
| `loadRichTexts` | boolean | Include HTML description content                                                 |
| `expandRecord`  | boolean | Expand nested/linked record fields                                               |
| `skipAncestors` | boolean | Skip loading parent records                                                      |

### Response[​](#response "Direct link to Response")

```
{
  "data": [
    {
      "id": "record-guid",
      "title": "Fix login timeout",
      "description": "<p>Users report...</p>",
      "creation_date": "2026-03-01T10:00:00.000Z",
      "update_date": "2026-03-20T15:30:00.000Z",
      "project_alias": "IT",
      "publishing_alias": "TICKET",
      "number": 123,
      "state": "open",
      "priority": "high",
      "resolved_values": {
        "state": "open",
        "created_by_account_id": "user-guid"
      },
      "_renderobj": {
        "keeper_id__resolved": "Alex Demo"
      },
      "transitions": ["edit", "close", "assign"],
      "amount_of_comments": 3,
      "__children_count": 2
    }
  ],
  "filteredRecordsCount": 125,
  "unfilteredRecordsCount": 150
}
```

Add `withTechnicalData=true` as a query parameter to get the structured response with `filteredRecordsCount` and `unfilteredRecordsCount`. Without it, the response is a plain array.

### Examples[​](#examples "Direct link to Examples")

**List all users:**

```
curl --request POST \
  --url "https://acme.comind.work/api/w/METAMETA/a/USER/tickets/list" \
  --header "Authorization: CMW_AUTH_CODE YOUR-TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"limitRecords": 100}'
```

**Filter tasks by priority and state:**

```
curl --request POST \
  --url "https://acme.comind.work/api/w/HELPDESK/a/TASK/tickets/list" \
  --header "Authorization: CMW_AUTH_CODE YOUR-TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"limitRecords": 10, "listOfFields": "priority,number,title", "rlx": "priority=\"normal\" AND state!=\"resolved\""}'
```

**TypeScript SDK:**

```
const tasks = await comind.records.retrieve(
  "w/HELPDESK/a/TASK/tickets/list",
  {
    limitRecords: 10,
    listOfFields: "priority,number,title",
    rlx: 'priority="normal" AND state!="resolved"',
  }
);
```

## Filter syntax (RLX)[​](#filter-syntax-rlx "Direct link to Filter syntax (RLX)")

Filters use a relational expression language called RLX:

```
state="open"
priority>"normal" AND creation_date>="2026-01-01"
(state="open" OR state="in_progress") AND keeper_id="user-guid"
```

### Operators[​](#operators "Direct link to Operators")

| Operator  | Example                                                       |
| --------- | ------------------------------------------------------------- |
| `=`       | `state="open"`                                                |
| `!=`      | `state!="resolved"`                                           |
| `>`, `>=` | `creation_date>="2026-01-01"`                                 |
| `<`, `<=` | `c_amount<1000`                                               |
| `AND`     | `state="open" AND priority="high"`                            |
| `OR`      | `state="open" OR state="in_progress"`                         |
| `()`      | Grouping: `(state="open" OR state="new") AND priority="high"` |

### Field names[​](#field-names "Direct link to Field names")

Filters use internal (db) field names. Common system fields:

| Field                   | Description                              |
| ----------------------- | ---------------------------------------- |
| `project_alias`         | Workspace alias (e.g., `"IT"`)           |
| `publishing_alias`      | App alias (e.g., `"TICKET"`)             |
| `keeper_id`             | Assignee (user GUID)                     |
| `created_by_account_id` | Record creator (user GUID)               |
| `update_account_id`     | Last updater (user GUID)                 |
| `state`                 | Current state (db value, e.g., `"open"`) |
| `creation_date`         | Record creation date                     |
| `update_date`           | Last modification date                   |

Person fields require the user's GUID, not their name. Use the schema endpoint to discover field names for a specific app.

tip

The [MCP tools](/api-integrations/ai/mcp-tools.md) layer adds convenience features on top of the raw API - field name aliases (`keeper` instead of `keeper_id`), person name resolution (names instead of GUIDs), link slug resolution (`"IT/TASK123"`), and `{current-user}` placeholders.

### In-list operators[​](#in-list-operators "Direct link to In-list operators")

For filtering against multiple values:

```
state in "open,in_progress,new":string[]
priority in "1,2,3":string[]
```

## Searching records[​](#searching-records "Direct link to Searching records")

**Endpoint:** `POST /api/tickets/search`

Full-text keyword search across records:

```
{
  "ss": "budget approval",
  "limitRecords": 10,
  "rlx": "project_alias=\"IT\""
}
```

| Parameter      | Type   | Description                           |
| -------------- | ------ | ------------------------------------- |
| `ss`           | string | Search keywords                       |
| `limitRecords` | number | Max results                           |
| `rlx`          | string | Additional filter to scope the search |

Response includes `totalFound` with the total number of matches.

### Search syntax[​](#search-syntax "Direct link to Search syntax")

* **Keywords:** `budget approval` - finds records containing either word
* **Exact phrase:** `"budget approval"` - wrapped in double quotes, matches the exact phrase
* **Exclude words:** `-draft` - prefix with `-` to exclude records containing that word
* **Combined:** `"budget approval" -draft` - exact phrase, excluding drafts
* Wildcards (`*`, `%`) are not supported - the system handles word variations automatically

Search results are sorted by relevance. Results include `__highlights` with matched snippets.

### Search vs list[​](#search-vs-list "Direct link to Search vs list")

* **Search** (`/tickets/search`) - keyword-based, full-text, searches across content and attachments, sorted by relevance
* **List** (`/tickets/list`) - field-based filtering, exact matches, sorted by any field
* Use search to discover records by content. Use list when you know which fields to filter on.

## Getting a workspace[​](#getting-a-workspace "Direct link to Getting a workspace")

**Endpoint:** `GET /api/projects/{wksAlias}`

Returns workspace details including installed apps and members:

```
{
  "alias": "IT",
  "title": "IT Department",
  "tabs": [
    { "process_alias": "TICKET", "resolved_caption": "Tickets", "position": 1 },
    { "process_alias": "TASK", "resolved_caption": "Tasks", "position": 2 }
  ],
  "workspace_users": [
    { "name": "Alex Demo", "role": "admin" }
  ]
}
```

## Getting an app schema[​](#getting-an-app-schema "Direct link to Getting an app schema")

**Endpoint:** `GET /api/schema/{workspace}!{app}`

Returns the full app schema - field definitions, lookup values, available actions, and form layouts:

```
{
  "id": "template-guid",
  "fields": {
    "state": {
      "name": "state",
      "ed_caption": "State",
      "ed_custom_field_type": "lookup"
    },
    "keeper_id": {
      "name": "keeper_id",
      "ed_caption": "Assignee",
      "ed_custom_field_type": "authorinfo"
    }
  },
  "lookups": {
    "state": [
      { "id": "open", "caption": "Open" },
      { "id": "done", "caption": "Done" }
    ]
  },
  "transitions": [
    { "alias": "edit", "caption": "Edit", "visible": true }
  ]
}
```

Use the schema to discover field names, lookup values, and available actions before building queries.

### Schema field properties[​](#schema-field-properties "Direct link to Schema field properties")

| Property                      | Description                                                                                   |
| ----------------------------- | --------------------------------------------------------------------------------------------- |
| `name`                        | Field db name (e.g., `"keeper_id"`)                                                           |
| `ed_caption`                  | Display label (string or localized object)                                                    |
| `ed_custom_field_type`        | Type marker: `"authorinfo"`, `"lookup_custom"`, `"lookup_link_to_entity"`, `"richtext"`, etc. |
| `field_type`                  | Data type: `"string"`, `"integer"`, `"datetime"`                                              |
| `ed_formatting_pre`           | Value prefix (e.g., `"$"`)                                                                    |
| `ed_formatting_post`          | Value suffix (e.g., `"h"`)                                                                    |
| `ed_default_value_expression` | Default value for new records                                                                 |
| `ed_help_text`                | Help text / tooltip                                                                           |

## Aggregating data[​](#aggregating-data "Direct link to Aggregating data")

**Endpoint:** `POST /api/w/{workspace}/a/{app}/tickets/list`

Use pivot parameters to get counts, sums, and breakdowns:

```
{
  "aggs4Pivot": true,
  "dimensions4Pivot": "state,keeper_id",
  "rlx": "creation_date>=\"2026-01-01\""
}
```

| Parameter          | Type    | Description                                  |
| ------------------ | ------- | -------------------------------------------- |
| `aggs4Pivot`       | boolean | Enable aggregation mode                      |
| `dimensions4Pivot` | string  | Comma-separated fields to group by           |
| `statsFields`      | string  | Numeric field for SUM/AVG/MIN/MAX (optional) |

### Response[​](#response-1 "Direct link to Response")

```
{
  "data": [
    {
      "state": "open",
      "state__resolved": "Open",
      "keeper_id__resolved": "Alex Demo",
      "_count": 25,
      "total_real": { "sum": 125.5, "avg": 5.02, "min": 0.5, "max": 20.0 }
    }
  ],
  "filteredRecordsCount": 125,
  "totalRecordsCount": 150
}
```

### Time-based pivoting[​](#time-based-pivoting "Direct link to Time-based pivoting")

Group by time periods using dimension suffixes:

| Suffix           | Groups by |
| ---------------- | --------- |
| `__pivotbyhour`  | Hour      |
| `__pivotbyday`   | Day       |
| `__pivotbymonth` | Month     |
| `__pivotbyyear`  | Year      |

Example: `"dimensions4Pivot": "keeper_id,creation_date__pivotbymonth"` groups by assignee and month.

## Record history[​](#record-history "Direct link to Record history")

**Endpoint:** `POST /api/tickets/history`

Retrieve the change history for records - who changed what, when:

```
{
  "limitRecords": 20,
  "sortby": "version_timestamp desc",
  "rlx": "id=\"record-guid\""
}
```

Response includes history entries with:

* `version_timestamp` - when the change was made
* `version_account_id__resolved` - who made the change
* `transition` - the action that was performed (e.g., "edit", "add", "comment")
* `comment` - HTML comment text
* Changed field values with `__resolved` suffixes for display values

## Permissions[​](#permissions "Direct link to Permissions")

All queries respect the authenticated user's permissions:

* Workspaces the user cannot access return empty results
* Fields the user cannot access are excluded from responses
* Record-level ACLs apply - some records may be filtered out
