Docs › API reference › Farm books & tasks
Farm books & tasks
The farm's custom books (logs, inventory, costs…), calendar and automation rules: read tables, read/add/edit rows.
57 operations · base /api/v1/office
/api/v1/office/appsList apps (paginated)
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
page | int | query | no | — |
pageSize | int | query | no | — |
search | string | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"hasNextPage": true,
"hasPreviousPage": true,
"items": [
{
"createdAt": "2026-10-28T07:30:00Z",
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"updatedAt": "2026-10-28T07:30:00Z"
}
],
"page": 1,
"pageSize": 1,
"totalCount": 1,
"totalPages": 1
}/api/v1/office/apps/{appId}/dashboardsList dashboards of an app
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
appId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<appId>/dashboards" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"createdAt": "2026-10-28T07:30:00Z",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"layout": {
"filters": [
{
"id": "…",
"kind": "…",
"label": "…",
"targets": [
null
]
}
],
"widgets": [
{
"aggregation": "…",
"columns": [
null
],
"compare": "…",
"dateField": "…",
"dateGrouping": "…",
"filter": {
"conditions": null,
"conjunction": null,
"groups": null,
"hasCriteria": null
},
"format": {
"decimals": null,
"prefix": null,
"style": null,
"suffix": null
},
"groupField": "…",
"h": 1,
"id": "…",
"limit": 1,
"orientation": "…",
"seriesField": "…",
"sort": "…",
"stacked": true,
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"target": 1.5,
"text": "…",
"title": "…",
"type": "…",
"valueField": "…",
"w": 1,
"x": 1,
"y": 1
}
]
},
"name": "…",
"position": 1,
"updatedAt": "2026-10-28T07:30:00Z"
}
]/api/v1/office/apps/{appId}/tablesList tables of an app
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
appId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<appId>/tables" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"position": 1
}
]/api/v1/office/apps/{appId}/tables/{tableId}Get a table
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
appId | GUID | path | yes | — |
tableId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<appId>/tables/<tableId>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"position": 1
}/api/v1/office/apps/{id}Get an app
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<id>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"createdAt": "2026-10-28T07:30:00Z",
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"updatedAt": "2026-10-28T07:30:00Z"
}/api/v1/office/automation-logsRun log, newest first
`result` filters by CODE: success · skipped · failed. Omit to return all results.
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
automationId | GUID | query | no | — |
result | string | query | no | — |
page | int | query | no | — |
pageSize | int | query | no | — |
enrollmentId | GUID | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"items": [
{
"automationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"detail": "…",
"detailKey": "…",
"enrollmentId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"result": "…",
"runAt": "2026-10-28T07:30:00Z",
"stepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"subjectId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
],
"page": 1,
"pageSize": 1,
"total": 1
}/api/v1/office/automation-logs/metricsOperational metrics for Automation in the company
Within `days` days (1–90): row counts by result, `failureRate`, `quotaBlocked` (number of times skipped due to the monthly run quota being exhausted), the monthly quota, and the queue: `activeRuns`, `dueRuns` (due but not yet picked up by the runner), `oldestDueSeconds` (how long the oldest due run has been waiting).
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
days | int | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs/metrics" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"activeRuns": 1,
"days": 1,
"dueRuns": 1,
"failed": 1,
"failureRate": 1.5,
"oldestDueSeconds": 1,
"quota": {
"limit": 1,
"month": "…",
"percent": 1.5,
"used": 1
},
"quotaBlocked": 1,
"skipped": 1,
"success": 1,
"total": 1
}/api/v1/office/automation-logs/runsHistory by RUN, newest first
A run = one data row passing through the rule once (grouped by `enrollmentId`). Each run: start/end, step count, failed/skipped/done counts and an overall `result` (failed > success > skipped). Open a run's details: `GET /automation-logs?enrollmentId=`. Server-side filters: `result` (success|failed|skipped|running) · `createdBy` (me|user ID — the rule's creator) · `from`/`to` (run start time, inclusive) · `search` (rule name, or exact run/row/rule ID).
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
automationId | GUID | query | no | — |
page | int | query | no | — |
pageSize | int | query | no | — |
result | string | query | no | — |
createdBy | string | query | no | — |
from | date | query | no | — |
to | date | query | no | — |
search | string | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs/runs" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"items": [
{
"automationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"automationName": "…",
"endedAt": "2026-10-28T07:30:00Z",
"enrollmentId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"failed": 1,
"result": "…",
"skipped": 1,
"startedAt": "2026-10-28T07:30:00Z",
"status": "…",
"steps": 1,
"subjectId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"subjectName": "…",
"succeeded": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
}/api/v1/office/automation-logs/statsThe four stat tiles at the top of the log screen
Counts per result CODE over the last `days` days (1–90).
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
automationId | GUID | query | no | — |
days | int | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs/stats" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"failed": 1,
"skipped": 1,
"success": 1,
"total": 1
}/api/v1/office/automation-templatesList the company's templates, newest first
`steps` is an ordered summary (step type + action) so the template gallery can show a line like "Send message → Wait → Branch".
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-templates" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"createdAt": "2026-10-28T07:30:00Z",
"createdBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"sourceAutomationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"stepCount": 1,
"steps": [
{
"actionType": "…",
"stepType": "…"
}
],
"triggerConfig": "…",
"triggerType": "…"
}
]/api/v1/office/automationsDanh sách automation
Paginated at the database. Filters: `status` (`active`·`inactive`·`draft`·`paused`·`archived`) · `failing=true` (has failed runs in the last 7 days) · `triggerType` · `createdBy` (`me` or user ID) · `tableId` · `actionType`; sort: `sort` (`updated`·`created`·`creator`·`name`, default `created`). Each row includes `stepCount`, `lastRunAt`, `runs7d`, `failed7d`, `createdById`, `createdByName`, `updatedAt`, `triggerConfig`, `stepActionTypes[]` — `steps` is left empty and loaded only when opening the details.
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
page | int | query | no | — |
pageSize | int | query | no | — |
search | string | query | no | — |
status | string | query | no | — |
triggerType | string | query | no | — |
createdBy | string | query | no | — |
tableId | GUID | query | no | — |
actionType | string | query | no | — |
sort | string | query | no | — |
failing | bool | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"hasNextPage": true,
"hasPreviousPage": true,
"items": [
{
"createdBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"createdById": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"createdByName": "…",
"description": "…",
"failed7d": 1,
"graphVersion": 1,
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"lastRunAt": "2026-10-28T07:30:00Z",
"name": "…",
"parentAutomationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"parentStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"runs7d": 1,
"source": "…",
"status": "…",
"stepActionTypes": [
"…"
],
"stepCount": 1,
"steps": [
{
"actionType": "…",
"branchIndex": 1,
"branchLabel": "…",
"conditionConfig": "…",
"config": "…",
"falseNextStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"groupId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"groupKind": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"loopAutomationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"nextStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"order": 1,
"splitRatio": 1,
"stepType": "…",
"trueNextStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"waitConfig": "…"
}
],
"triggerConfig": "…",
"triggerType": "…",
"updatedAt": "2026-10-28T07:30:00Z"
}
],
"page": 1,
"pageSize": 1,
"totalCount": 1,
"totalPages": 1
}/api/v1/office/automations/ai-columns/catalogCatalog of AI column modes
AI column modes usable in automations. `available: false` means the feature is not enabled for this workspace: the column can still be configured but does not generate content yet.
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/ai-columns/catalog" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"available": true,
"modes": [
{
"labelKey": "…",
"mode": "…",
"needsOptions": true,
"needsRange": true
}
]
}/api/v1/office/automations/catalogCatalog of triggers/actions available for building automations
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/catalog" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"actions": [
{
"configFields": [
{
"description": "…",
"input": "…",
"label": "…",
"name": "…",
"options": [
null
],
"optionsSource": "…",
"required": true,
"type": "…"
}
],
"description": "…",
"group": "…",
"label": "…",
"type": "…"
}
],
"steps": [
{
"configFields": [
{
"description": "…",
"input": "…",
"label": "…",
"name": "…",
"options": [
null
],
"optionsSource": "…",
"required": true,
"type": "…"
}
],
"description": "…",
"group": "…",
"label": "…",
"type": "…"
}
],
"triggers": [
{
"configFields": [
{
"description": "…",
"input": "…",
"label": "…",
"name": "…",
"options": [
null
],
"optionsSource": "…",
"required": true,
"type": "…"
}
],
"description": "…",
"group": "…",
"label": "…",
"type": "…"
}
]
}/api/v1/office/automations/merge-fieldsCatalog of {{…}} variables insertable into action configuration
For the "insert variable" field of the rule builder. `triggerType` = the rule's trigger code ⇒ adds the `system` group (`now`, `today`, `createdBy`) and a `trigger` group based on the code (e.g. `before.<column>`, `changedFields`, `trigger.runNumber`, `trigger.clickedByName`).`tableId` = the rule's trigger table; if empty, only the trigger data group is returned. Each item has a `token` — the text placed inside `{{ }}`. Every text field in the configuration of EVERY action accepts variables; a variable that cannot be resolved at run time stays verbatim in the output (Test run lists them under `unresolved`). `automationId` + `stepId` ⇒ adds a `scope = "step"` group (with `stepId`) for EACH Find rows / Add rows step preceding that step: `steps.<step code>.recordIds` · `.count` · `.<Column name>` · `.first.<Column name>`. A `stepId` not yet in the rule (a step about to be added) ⇒ treated as the last step. Phase 4: `message_received` ⇒ `trigger.text` · `senderName` · `attachments` · `mentionNames` · `channelName` · `link`…; `service_event` ⇒ `trigger.payload.<key>` from the catalog of `eventType` (a parameter, or read from the configuration of `automationId`).
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | query | no | — |
triggerType | string | query | no | — |
automationId | GUID | query | no | — |
stepId | GUID | query | no | — |
eventType | string | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/merge-fields" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"fields": [
{
"example": "…",
"label": "…",
"token": "…"
}
],
"label": "…",
"scope": "…",
"stepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
]/api/v1/office/automations/quotaThe company's monthly run quota
`{ month: "yyyy-MM" (Vietnam time), used, limit, percent }`. A run = one rule trigger (child runs of a loop are not counted). Over 100% ⇒ new runs are skipped and the log records the reason `quota_exceeded`; users' data operations do not fail.
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/quota" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"limit": 1,
"month": "…",
"percent": 1.5,
"used": 1
}/api/v1/office/automations/service-eventsCatalog of events from other software (service_event trigger)
`[{ service, label, events: [{ code, label, requiresFilter, perMinuteCap, keys: [{ key, label, type, token }] }] }]` — software → event → data key (Vietnamese labels). `code` goes into `eventType` of the WHEN configuration; `key` goes into `filters.groups[].rules[].key`; `token` is the insertable variable (`trigger.payload.<key>`). `type`: text · number · date · datetime · id · boolean. This catalog is exactly the list of system events currently received — a rule whose `eventType` is no longer here is `event_unknown` (cannot be re-enabled).
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/service-events" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"events": [
{
"code": "…",
"keys": [
{
"key": null,
"label": null,
"token": null,
"type": null
}
],
"label": "…",
"perMinuteCap": 1,
"requiresFilter": true
}
],
"label": "…",
"service": "…"
}
]/api/v1/office/automations/suggestionsAutomation suggestions tailored to the company (Suggestions tab)
Up to 3 cards `[{ kind, triggerType, actionType, tableId, tableName, fieldId, fieldName, offsetDays, evidenceCount, evidenceDays, existingAutomationId, existingAutomationName, existingStatus, existingRuns, existingFailed }]` built from real data: `date_expiring` = a Date column named like "Expiry date" with rows due within the next 30 days (suggests an "On date" rule, 30 days before); `busy_table` = a table with many new rows in the last 30 days that no rule listens to yet. `existingAutomationId` present = the company already has this rule (with run/failure counts over the last 30 days). The server returns only codes + numbers; the wording is translated by the UI. Read-only.
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/suggestions" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"actionType": "…",
"eventType": "…",
"evidenceCount": 1,
"evidenceDays": 1,
"existingAutomationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"existingAutomationName": "…",
"existingFailed": 1,
"existingRuns": 1,
"existingStatus": "…",
"fieldId": "…",
"fieldName": "…",
"kind": "…",
"offsetDays": 1,
"service": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"tableName": "…",
"triggerType": "…"
}
]/api/v1/office/automations/summaryCounts for the Automation Center
`{ total, active, inactive, mine, byTrigger: { [trigger code]: n }, archived, failing }` — `inactive` = all rules not Active; `archived` ⊂ `inactive`; `failing` = rules with failed runs in the last 7 days.
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/summary" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"active": 1,
"archived": 1,
"byTrigger": {
"key": 1
},
"failing": 1,
"inactive": 1,
"mine": 1,
"total": 1
}/api/v1/office/automations/{id}Get an automation (with steps)
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"createdBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"createdById": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"createdByName": "…",
"description": "…",
"failed7d": 1,
"graphVersion": 1,
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"lastRunAt": "2026-10-28T07:30:00Z",
"name": "…",
"parentAutomationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"parentStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"runs7d": 1,
"source": "…",
"status": "…",
"stepActionTypes": [
"…"
],
"stepCount": 1,
"steps": [
{
"actionType": "…",
"branchIndex": 1,
"branchLabel": "…",
"conditionConfig": "…",
"config": "…",
"falseNextStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"groupId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"groupKind": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"loopAutomationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"nextStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"order": 1,
"splitRatio": 1,
"stepType": "…",
"trueNextStepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"waitConfig": "…"
}
],
"triggerConfig": "…",
"triggerType": "…",
"updatedAt": "2026-10-28T07:30:00Z"
}/api/v1/office/automations/{id}/diagnosisDiagnostics: why a rule runs / does not run
Checks in order (`status` · `trigger` · `steps` · `quota` · `recent_failures`), `canRun` = no blocking check failed, the 5 most recent SKIPS with translated reasons, and the most recent failure. Read-only.
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>/diagnosis" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"canRun": true,
"checks": [
{
"blocking": true,
"code": "…",
"detail": "…",
"ok": true
}
],
"lastFailure": {
"automationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"detail": "…",
"detailKey": "…",
"enrollmentId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"result": "…",
"runAt": "2026-10-28T07:30:00Z",
"stepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"subjectId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
},
"recentSkips": [
{
"automationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"detail": "…",
"detailKey": "…",
"enrollmentId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"result": "…",
"runAt": "2026-10-28T07:30:00Z",
"stepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"subjectId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
],
"status": "…"
}/api/v1/office/automations/{id}/overlapsOther rules with the same trigger doing the same thing
Other ENABLED rules of the company with the same trigger type, the same listening scope (table, column, event type, channel — filters ignored) and at least one action type in common with this rule, with `sharedActions`. Warning only: with different filters the two rules may never run together; the user decides. Maximum 10.
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>/overlaps" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"sharedActions": [
"…"
]
}
]/api/v1/office/automations/{id}/webhook/sampleData sample + key tree
`{ sample, sampleSource: listen|manual, sampleAt, listening, listenUntil, keys: [{ name, path: "trigger.payload.a.b", type, example, children }] }`. `path` is the variable inserted into the step configuration. No sample yet ⇒ sample null, keys [].
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>/webhook/sample" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"keys": [
{
"children": [
{
"children": [
null
],
"example": "…",
"name": "…",
"path": "…",
"type": "…"
}
],
"example": "…",
"name": "…",
"path": "…",
"type": "…"
}
],
"listenUntil": "2026-10-28T07:30:00Z",
"listening": true,
"sample": null,
"sampleAt": "2026-10-28T07:30:00Z",
"sampleSource": "…"
}/api/v1/office/calendar-linksMy calendar connection status
providerConfigured = false means the server has no Google connection key — the UI must say 'not enabled by an admin', not 'you haven't connected'.
office.calendar.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendar-links" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"accountEmail": "…",
"calendarId": "…",
"connected": true,
"lastErrorKey": "…",
"lastSyncedAt": "2026-10-28T07:30:00Z",
"provider": "…",
"providerConfigured": true,
"status": "…"
}/api/v1/office/calendar-links/meeting-providersEnabled online meeting providers
Returns ONLY providers whose connection keys are fully configured on the server. The UI must build its picker from this list instead of hard-coding it — if a company has not enabled Teams but still sees a Teams option, selecting it just yields an error. connected = false means the user has not linked their account, which is entirely different from 'not enabled by an admin'.
office.calendar.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendar-links/meeting-providers" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"code": "…",
"connected": true,
"linkFromCalendarEvent": true
}
]/api/v1/office/calendar-preferencesMy calendar screen settings
office.calendar.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendar-preferences" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"dayEndHour": 1,
"dayStartHour": 1,
"defaultEventMinutes": 1,
"defaultView": "…",
"showDeclined": true,
"showWeekends": true,
"timeZone": "…",
"weekStartDay": 1
}/api/v1/office/calendarsCalendars I am subscribed to (left column)
office.calendar.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendars" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"color": "…",
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isMine": true,
"isSubscribed": true,
"isVisible": true,
"kind": "…",
"name": "…",
"ownerId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"ownerName": "…",
"role": "…"
}
]/api/v1/office/calendars/subscribableCalendars available to subscribe to
Returns only calendars the caller is ACTUALLY allowed to see: shared calendars and holiday calendars.
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
term | string | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendars/subscribable" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"color": "…",
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isMine": true,
"isSubscribed": true,
"isVisible": true,
"kind": "…",
"name": "…",
"ownerId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"ownerName": "…",
"role": "…"
}
]/api/v1/office/connection-keysList issued keys
NEVER returns the actual key — only the identifying `prefix`. `status` is a CODE: active · revoked.
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/connection-keys" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"createdAt": "2026-10-28T07:30:00Z",
"expiresAt": "2026-10-28T07:30:00Z",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"lastUsedAt": "2026-10-28T07:30:00Z",
"name": "…",
"prefix": "…",
"status": "…"
}
]/api/v1/office/dashboards/{id}/widgets/{widgetId}/dataFigures for one tile, computed per the viewer's permissions
unavailable = table_missing (table deleted) | no_access (the tile reads a column/table the viewer is not allowed to see).
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
widgetId | string | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/dashboards/<id>/widgets/<widgetId>/data" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"buckets": [
{
"count": 1,
"key": "…",
"value": 1.5
}
],
"comparePeriod": {
"from": "…",
"previousFrom": "…",
"previousTo": "…",
"to": "…"
},
"count": 1,
"deltaPercent": 1.5,
"groups": [
{
"count": 1,
"key": "…",
"series": [
{
"count": 1,
"key": "…",
"value": 1.5
}
],
"value": 1.5
}
],
"previousValue": 1.5,
"rows": [
{
"cells": {
"key": null
},
"recordId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
],
"seriesKeys": [
"…"
],
"target": 1.5,
"truncated": true,
"type": "…",
"unavailable": "…",
"value": 1.5,
"widgetId": "…"
}/api/v1/office/eventsEvents within a time range
Used for week and month calendar views. Maximum query range is 120 days. eventType and status are returned as English CODES. truncated=true means the list was cut by a safety cap (too many events or too many recurrences in the visible window) — narrow the range to see everything.
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
from | date | query | no | — |
to | date | query | no | — |
eventType | string | query | no | — |
mineOnly | bool | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/events" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"entries": [
{
"allDay": true,
"attendeeCount": 1,
"calendarColor": "…",
"calendarId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"contentVisible": true,
"endAt": "2026-10-28T07:30:00Z",
"eventId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"eventType": "…",
"fromPersonalCalendar": true,
"id": "…",
"isRecurring": true,
"meetingUrl": "…",
"myResponse": "…",
"occurrenceStart": "2026-10-28T07:30:00Z",
"organizerId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"roomNames": [
"…"
],
"startAt": "2026-10-28T07:30:00Z",
"status": "…",
"title": "…"
}
],
"truncated": true
}/api/v1/office/events/{id}Get an event with its attendees and booked rooms
occurrenceStart is the ORIGINAL timestamp of one occurrence in a recurring series — when provided, the title, time, description and location returned are the version WITH that occurrence's exceptions APPLIED, not the series-wide version. Omit for non-recurring events, or to view/edit the whole series (scope=all).
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
occurrenceStart | date | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/events/<id>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"allDay": true,
"attendees": [
{
"email": "…",
"isOptional": true,
"isOrganizer": true,
"responseNote": "…",
"responseStatus": "…",
"userId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
],
"calendarId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"chatChannelId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"description": "…",
"endAt": "2026-10-28T07:30:00Z",
"eventType": "…",
"fromPersonalCalendar": true,
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"location": "…",
"meetingProvider": "…",
"meetingRemovalPending": true,
"meetingUrl": "…",
"organizerId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"pushErrorKey": "…",
"pushPending": true,
"recurrenceRule": "…",
"remindBeforeMinutes": 1,
"reminders": [
{
"channel": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"minutesBefore": 1
}
],
"rooms": [
{
"bookingId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"name": "…",
"roomId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"status": "…"
}
],
"startAt": "2026-10-28T07:30:00Z",
"status": "…",
"syncedWithGoogle": true,
"timeProposals": [
{
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"note": "…",
"occurrenceStart": "2026-10-28T07:30:00Z",
"proposedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"proposedByName": "…",
"proposedEndAt": "2026-10-28T07:30:00Z",
"proposedStartAt": "2026-10-28T07:30:00Z",
"status": "…"
}
],
"title": "…"
}/api/v1/office/events/{id}.icsDownload the event's .ics calendar file
For signed-in users INSIDE the company (organizer/attendee/calendar shared at a sufficient level). External guests use the separate public link in the invitation — see PublicCalendarController, NOT this endpoint.
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/events/<id>.ics" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
"…"/api/v1/office/farm/device-controlsList command tickets
status: pending · dispatched · rejected · expired. scope: mine (tickets I can approve) · all.
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
status | string | query | no | — |
scope | string | query | no | — |
take | int | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/farm/device-controls" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"approverIds": [
"0190a3c2-5b1e-7c3d-8e4f-000000000001"
],
"automationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"canDecide": true,
"createdAt": "2026-10-28T07:30:00Z",
"decidedAt": "2026-10-28T07:30:00Z",
"decidedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"deviceId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"deviceLabel": "…",
"expiresAt": "2026-10-28T07:30:00Z",
"family": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"idx": 1,
"iotCommandId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"note": "…",
"reason": "…",
"status": "…",
"value": 1
}
]/api/v1/office/farm/device-controls/emergency-stopEMERGENCY STOP status of the farm's automatic device control
office.automation.viewTry in API Explorer ▶Parameter
No parameters.
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/farm/device-controls/emergency-stop" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"canChange": true,
"changedAt": "2026-10-28T07:30:00Z",
"changedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"stopped": true
}/api/v1/office/farm/device-controls/rules/{automationId}/approvalAuto-run approval status of a rule
valid = the approval stamp still matches the rule and table data (editing the rule / schedule invalidates it).
office.automation.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
automationId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/farm/device-controls/rules/<automationId>/approval" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"approved": true,
"approvedAt": "2026-10-28T07:30:00Z",
"approvedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"automationId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"canApprove": true,
"valid": true
}/api/v1/office/meeting-minutesMinutes of a meeting
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
eventId | GUID | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/meeting-minutes" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"actionItems": [
{
"assigneeId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"description": "…",
"dueAt": "2026-10-28T07:30:00Z",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"taskId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
],
"artifactsFetchedAt": "2026-10-28T07:30:00Z",
"decisions": "…",
"eventId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"publishedAt": "2026-10-28T07:30:00Z",
"recordedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"recordingUrl": "…",
"summary": "…",
"transcriptText": "…"
}/api/v1/office/meeting-roomsList meeting rooms
minCapacity/equipment/building filter right in the room picker — equipment requires the room to have ALL requested codes.
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
activeOnly | bool | query | no | — |
minCapacity | int | query | no | — |
equipment | object | query | no | — |
building | string | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/meeting-rooms" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"autoReleaseMinutes": 1,
"building": "…",
"capacity": 1,
"equipment": [
"…"
],
"floor": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isActive": true,
"location": "…",
"maxBookingMinutes": 1,
"name": "…",
"requiresApproval": true
}
]/api/v1/office/meeting-rooms/{id}/busy-slotsBusy time slots of a room
Called by the UI as soon as the user picks a room, to grey out unavailable slots.
office.calendar.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
id | GUID | path | yes | — |
from | date | query | no | — |
to | date | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/meeting-rooms/<id>/busy-slots" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"bookedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"endAt": "2026-10-28T07:30:00Z",
"eventId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"eventTitle": "…",
"startAt": "2026-10-28T07:30:00Z"
}
]/api/v1/office/tables/{tableId}/fieldsList fields of a table
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/fields" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isHidden": true,
"isPrimary": true,
"name": "…",
"position": 1,
"property": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"type": 1,
"uiType": "…"
}
]/api/v1/office/tables/{tableId}/fields/{fieldId}Get a field
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
fieldId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/fields/<fieldId>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"description": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isHidden": true,
"isPrimary": true,
"name": "…",
"position": 1,
"property": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"type": 1,
"uiType": "…"
}/api/v1/office/tables/{tableId}/recordsCreate a record
Mobile writes while offline: send the X-Submission-Id header (device-generated uuid) + X-Captured-At (actual capture time, ISO-8601). Resending the same ID ⇒ returns the existing row, no duplicate is created.
office.base.record.manageTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
data | string | body | no | — |
Example
curl -X POST "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "data": null }'Sample response
201 Created
null/api/v1/office/tables/{tableId}/records/aggregateAggregate by column (sum · average · min · max · count)
The five figures of the footer bar, computed over the CURRENTLY FILTERED set — send exactly the filters the grid is applying. Summed on the server, not in the grid: the grid only holds a few hundred rows around the scroll position, so summing what it holds would make the figures JUMP as the user scrolls. Columns outside the viewable scope are excluded from the result. This is not a formula engine: no syntax, no `A1:A10` ranges, nothing is stored.
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
fieldIds | object | body | no | — |
filter | object | body | no | — |
Example
curl -X POST "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/aggregate" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "fieldIds": [ "0190a3c2-5b1e-7c3d-8e4f-000000000001" ], "filter": { "conditions": [ { "fieldId": "…", "operator": "…", "value": null } ], "conjunction": "…", "groups": [ { "conditions": [ { "fieldId": null, "operator": null, "value": null } ], "conjunction": "…", "groups": [ { "conditions": null, "conjunction": null, "groups": null, "hasCriteria": null } ], "hasCriteria": true } ], "hasCriteria": true } }'Sample response
200 OK
[
{
"average": 1.5,
"count": 1,
"fieldId": "…",
"max": 1.5,
"min": 1.5,
"numericCount": 1,
"sum": 1.5
}
]/api/v1/office/tables/{tableId}/records/batchCreate multiple records (up to 1000, all-or-nothing)
office.base.record.manageTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
records | object | body | no | — |
Example
curl -X POST "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/batch" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "records": [ null ] }'Sample response
201 Created
null/api/v1/office/tables/{tableId}/records/batchUpdate multiple records (up to 1000, all-or-nothing)
office.base.record.manageTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
items | object | body | no | — |
Example
curl -X PUT "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/batch" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "items": [ { "data": null, "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001", "replace": true } ] }'Sample response
This endpoint does not declare a response schema yet — call it in the API Explorer to see the shape.
/api/v1/office/tables/{tableId}/records/groupsRow groups: group column value + row count, in the same order as records/list
Send the SAME filter/sort/groupFieldId as records/list — the grid accumulates row counts to place group headers. If the group column is outside view permissions ⇒ fieldHidden=true, with no groups.
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
filter | object | body | no | — |
groupFieldId | string | body | no | — |
sort | object | body | no | — |
Example
curl -X POST "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/groups" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "filter": { "conditions": [ { "fieldId": "…", "operator": "…", "value": null } ], "conjunction": "…", "groups": [ { "conditions": [ { "fieldId": null, "operator": null, "value": null } ], "conjunction": "…", "groups": [ { "conditions": null, "conjunction": null, "groups": null, "hasCriteria": null } ], "hasCriteria": true } ], "hasCriteria": true }, "groupFieldId": "…", "sort": [ { "descending": true, "fieldId": "…" } ] }'Sample response
200 OK
{
"fieldHidden": true,
"groups": [
{
"count": 1,
"value": null
}
],
"tooMany": true,
"total": 1
}/api/v1/office/tables/{tableId}/records/listList records (paginated + structured filter in the body)
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
colorRules | object | body | no | — |
filter | object | body | no | — |
groupFieldId | string | body | no | — |
page | int | body | no | — |
pageSize | int | body | no | — |
sort | object | body | no | — |
Example
curl -X POST "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/list" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "colorRules": [ { "color": "…", "filter": { "conditions": [ { "fieldId": null, "operator": null, "value": null } ], "conjunction": "…", "groups": [ { "conditions": null, "conjunction": null, "groups": null, "hasCriteria": null } ], "hasCriteria": true } } ], "filter": { "conditions": [ { "fieldId": "…", "operator": "…", "value": null } ], "conjunction": "…", "groups": [ { "conditions": [ { "fieldId": null, "operator": null, "value": null } ], "conjunction": "…", "groups": [ { "conditions": null, "conjunction": null, "groups": null, "hasCriteria": null } ], "hasCriteria": true } ], "hasCriteria": true }, "groupFieldId": "…", "page": 1, "pageSize": 1, "sort": [ { "descending": true, "fieldId": "…" } ] }'Sample response
200 OK
{
"hasNextPage": true,
"hasPreviousPage": true,
"items": [
{
"createdAt": "2026-10-28T07:30:00Z",
"data": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"rowColor": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"updatedAt": "2026-10-28T07:30:00Z"
}
],
"page": 1,
"pageSize": 1,
"totalCount": 1,
"totalPages": 1
}/api/v1/office/tables/{tableId}/records/{recordId}Get a record
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
recordId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/<recordId>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"createdAt": "2026-10-28T07:30:00Z",
"data": "…",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"rowColor": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"updatedAt": "2026-10-28T07:30:00Z"
}/api/v1/office/tables/{tableId}/records/{recordId}Update a record (merge by default; replace=true to overwrite)
Send `expectedValues` — a map of field_id → the value the UI is CURRENTLY SHOWING for exactly the cells being edited — to enable optimistic locking. If any cell has been changed by someone else, the call returns **409** with the list of conflicting cells and their current values, and **no cell is written**. Omit `expectedValues` to skip the check, as before — so existing clients keep their behaviour.
office.base.record.manageTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
recordId | GUID | path | yes | — |
data | string | body | no | — |
expectedValues | string | body | no | — |
replace | bool | body | no | — |
Example
curl -X PUT "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/<recordId>" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "data": null, "expectedValues": null, "replace": true }'Sample response
This endpoint does not declare a response schema yet — call it in the API Explorer to see the shape.
/api/v1/office/tables/{tableId}/records/{recordId}/historyEdit history of a record, split by cell (filtered by column permissions)
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
recordId | GUID | path | yes | — |
limit | int | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/<recordId>/history" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"action": "…",
"changes": [
{
"fieldId": "…",
"fieldName": "…",
"fieldType": 1,
"newValue": null,
"oldValue": null
}
],
"createdAt": "2026-10-28T07:30:00Z",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"userId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
]/api/v1/office/tables/{tableId}/trashTrash — soft-deleted records of a table (paginated)
Only records of the current company; data is intact and can be restored or permanently deleted.
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
page | int | query | no | — |
pageSize | int | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/trash" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"hasNextPage": true,
"hasPreviousPage": true,
"items": [
{
"createdAt": "2026-10-28T07:30:00Z",
"data": "…",
"deletedAt": "2026-10-28T07:30:00Z",
"deletedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"updatedAt": "2026-10-28T07:30:00Z"
}
],
"page": 1,
"pageSize": 1,
"totalCount": 1,
"totalPages": 1
}/api/v1/office/tables/{tableId}/viewsList views of a table
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isPublic": true,
"name": "…",
"property": "…",
"publicToken": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"viewType": "…"
}
]/api/v1/office/tables/{tableId}/views/{viewId}Get a view
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
viewId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views/<viewId>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isPublic": true,
"name": "…",
"property": "…",
"publicToken": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"viewType": "…"
}/api/v1/office/tables/{tableId}/views/{viewId}/calendar-dataRecords within the date range of a Calendar view
Maps date fields (startField/endField) in property; from/to filter by start date.
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
viewId | GUID | path | yes | — |
from | date | query | no | — |
to | date | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views/<viewId>/calendar-data" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"data": "…",
"end": "2026-10-28T07:30:00Z",
"recordId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"start": "2026-10-28T07:30:00Z"
}
]/api/v1/office/tables/{tableId}/views/{viewId}/chart-dataAggregated data for a Chart view
Grouped per the configuration in property (groupField + aggregation count/sum/avg). The FE renders it.
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
tableId | GUID | path | yes | — |
viewId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views/<viewId>/chart-data" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"aggregation": "…",
"buckets": [
{
"count": 1,
"groupKey": "…",
"value": 1.5
}
],
"groupField": "…",
"valueField": "…"
}/api/v1/office/tasks/monitorMonitoring screen: six stat tiles + team-wide table + each person's tasks
One call returns all three parts because they read THE SAME task set — splitting them would put the stat tiles and the table below at two different points in time with mismatched numbers. elapsedMinutes is the time ELAPSED since work started (started_at), NOT labour hours. loadState: overloaded · normal · free. isExact=false means the company exceeds the row cap so all figures are estimates. taskListId narrows ALL figures to one project — it only narrows and never reveals tasks the scope would not otherwise show. With taskListId, each member row also carries openCountAll = that person's open tasks across the whole scope. Each member's items are capped at 200 (overdue first); openTotal = the ACTUAL total of that person's open tasks in the same scope — compare with the number of items to show “showing n/N”. dueSoonDays = the “due soon” window currently applied (alongside staleAfterDays).
office.task.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
scope | string | query | no | — |
taskListId | GUID | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tasks/monitor" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"dueSoonDays": 1,
"isExact": true,
"members": [
{
"current": {
"elapsedMinutes": 1,
"startedAt": "2026-10-28T07:30:00Z",
"taskId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"title": "…"
},
"dueSoonCount": 1,
"hasOnTimeData": true,
"inProgressCount": 1,
"items": [
{
"daysLate": 1,
"dueAt": "2026-10-28T07:30:00Z",
"id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"isOverdue": true,
"status": "…",
"title": "…"
}
],
"lastActivityAt": "2026-10-28T07:30:00Z",
"loadState": "…",
"onTimeRate": 1,
"openCount": 1,
"openCountAll": 1,
"openTotal": 1,
"overdueCount": 1,
"pendingReviewCount": 1,
"staleCount": 1,
"todoCount": 1,
"userId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
}
],
"staleAfterDays": 1,
"summary": {
"dueSoon": 1,
"hasOnTimeData": true,
"onTimeRate": 1,
"open": 1,
"overdue": 1,
"stale": 1,
"unassigned": 1
}
}/api/v1/office/tasks/workloadWorkload per person
isOverloaded is relative to the overload threshold, default 10 open tasks; each row also returns overloadThreshold = the threshold applied. Workload is for REFERENCE ONLY, not for computing progress. taskListId narrows to one list; listGroupId narrows to one folder (team) INCLUDING all subfolders. With both, the INTERSECTION applies. A non-existent list/folder ⇒ 404.
office.task.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
taskListId | GUID | query | no | — |
listGroupId | GUID | query | no | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tasks/workload" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
[
{
"isOverloaded": true,
"openCount": 1,
"overdueCount": 1,
"overloadThreshold": 1,
"totalWorkload": 1.5,
"userId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"workloadDay": 1.5,
"workloadHour": 1.5,
"workloadPoint": 1.5
}
]/api/v1/office/views/{viewId}/locationTrace back from a view ID to the table and app that contain it
office.base.record.viewTry in API Explorer ▶Parameter
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
viewId | GUID | path | yes | — |
Example
curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/views/<viewId>/location" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Sample response
200 OK
{
"appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"appName": "…",
"tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"tableName": "…",
"viewId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
"viewName": "…",
"viewType": "…"
}