Tài liệu › Tham chiếu API › Sổ nông trại & công việc

Sổ nông trại & công việc

Sổ tự dựng của trại (nhật ký, kho, chi phí…), lịch, luật tự động hoá: đọc bảng, đọc/thêm/sửa dòng.

57 thao tác · gốc /api/v1/office

GET/api/v1/office/apps

Liệt kê app (phân trang)

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
pageintquerykhông—
pageSizeintquerykhông—
searchstringquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/apps/{appId}/dashboards

Liệt kê bảng điều khiển của một ứng dụng

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
appIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<appId>/dashboards" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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"
  }
]
GET/api/v1/office/apps/{appId}/tables

Liệt kê table của app

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
appIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<appId>/tables" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "name": "…",
    "position": 1
  }
]
GET/api/v1/office/apps/{appId}/tables/{tableId}

Lấy chi tiết table

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
appIdGUIDpathcó—
tableIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<appId>/tables/<tableId>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "name": "…",
  "position": 1
}
GET/api/v1/office/apps/{id}

Lấy chi tiết app

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/apps/<id>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "createdAt": "2026-10-28T07:30:00Z",
  "description": "…",
  "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "name": "…",
  "updatedAt": "2026-10-28T07:30:00Z"
}
GET/api/v1/office/automation-logs

Nhật ký chạy, mới nhất trước

`result` lọc theo MÃ: success · skipped · failed. Bỏ trống thì trả về mọi kết quả.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
automationIdGUIDquerykhông—
resultstringquerykhông—
pageintquerykhông—
pageSizeintquerykhông—
enrollmentIdGUIDquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/automation-logs/metrics

Chỉ số vận hành của Tự động hoá trong công ty

Trong `days` ngày (1–90): số dòng theo kết quả, `failureRate`, `quotaBlocked` (số lần bị bỏ qua vì hết lượt chạy tháng), hạn mức tháng, và hàng đợi: `activeRuns`, `dueRuns` (đã tới hạn mà bộ chạy chưa lấy), `oldestDueSeconds` (lượt tới hạn cũ nhất đã đợi bao lâu).

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
daysintquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs/metrics" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/automation-logs/runs

Lịch sử theo LƯỢT CHẠY, mới nhất trước

Một lượt = một dòng dữ liệu đi qua luật một lần (gom theo `enrollmentId`). Mỗi lượt: bắt đầu/kết thúc, số bước, số hỏng/bỏ qua/xong và `result` tổng (failed > success > skipped). Mở chi tiết một lượt: `GET /automation-logs?enrollmentId=`. Lọc ở máy chủ: `result` (success|failed|skipped|running) · `createdBy` (me|mã người — người tạo luật) · `from`/`to` (mốc bắt đầu lượt, bao gồm) · `search` (tên luật, hoặc đúng mã lượt/dòng/luật).

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
automationIdGUIDquerykhông—
pageintquerykhông—
pageSizeintquerykhông—
resultstringquerykhông—
createdBystringquerykhông—
fromdatequerykhông—
todatequerykhông—
searchstringquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs/runs" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/automation-logs/stats

Bốn ô số liệu trên đầu màn nhật ký

Đếm theo từng MÃ kết quả trong `days` ngày gần nhất (1–90).

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
automationIdGUIDquerykhông—
daysintquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-logs/stats" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "failed": 1,
  "skipped": 1,
  "success": 1,
  "total": 1
}
GET/api/v1/office/automation-templates

Danh sách mẫu của công ty, mới nhất trước

`steps` là tóm tắt theo thứ tự (kiểu bước + hành động) để kho mẫu hiện dòng "Gửi tin → Chờ → Rẽ nhánh".

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automation-templates" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
  }
]
GET/api/v1/office/automations

Danh sách automation

Phân trang ở cơ sở dữ liệu. Lọc: `status` (`active`·`inactive`·`draft`·`paused`·`archived`) · `failing=true` (có lượt lỗi 7 ngày qua) · `triggerType` · `createdBy` (`me` hoặc mã người) · `tableId` · `actionType`; sắp: `sort` (`updated`·`created`·`creator`·`name`, mặc định `created`). Mỗi dòng kèm `stepCount`, `lastRunAt`, `runs7d`, `failed7d`, `createdById`, `createdByName`, `updatedAt`, `triggerConfig`, `stepActionTypes[]` — `steps` để rỗng, mở chi tiết mới tải.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
pageintquerykhông—
pageSizeintquerykhông—
searchstringquerykhông—
statusstringquerykhông—
triggerTypestringquerykhông—
createdBystringquerykhông—
tableIdGUIDquerykhông—
actionTypestringquerykhông—
sortstringquerykhông—
failingboolquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/automations/ai-columns/catalog

Danh mục chế độ của cột AI

Các chế độ cột AI dùng được trong tự động hoá. `available: false` nghĩa là tính năng chưa bật cho không gian làm việc này: cột vẫn cấu hình được nhưng chưa tạo nội dung.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/ai-columns/catalog" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "available": true,
  "modes": [
    {
      "labelKey": "…",
      "mode": "…",
      "needsOptions": true,
      "needsRange": true
    }
  ]
}
GET/api/v1/office/automations/catalog

Catalog trigger/action khả dụng để dựng automation

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/catalog" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
    }
  ]
}
GET/api/v1/office/automations/merge-fields

Danh mục biến {{…}} chèn được vào cấu hình hành động

Cho ô "chèn biến" của trình dựng luật. `triggerType` = mã kích hoạt của luật ⇒ thêm nhóm `system` (`now`, `today`, `createdBy`) và nhóm `trigger` theo mã (vd `before.<cột>`, `changedFields`, `trigger.runNumber`, `trigger.clickedByName`).`tableId` = bảng kích hoạt của luật; bỏ trống thì chỉ có nhóm dữ liệu kích hoạt. Mỗi mục có `token` — chữ đặt giữa `{{ }}`. Mọi ô chữ trong cấu hình của MỌI hành động đều điền được biến; biến không tra được lúc chạy thì nằm nguyên văn trong kết quả (Chạy thử liệt kê chúng ở `unresolved`). `automationId` + `stepId` ⇒ thêm nhóm `scope = "step"` (kèm `stepId`) cho MỖI bước Tìm dòng / Thêm dòng đứng trước bước đó: `steps.<mã bước>.recordIds` · `.count` · `.<Tên cột>` · `.first.<Tên cột>`. `stepId` chưa có trong luật (bước sắp thêm) ⇒ coi như bước cuối. Đợt 4: `message_received` ⇒ `trigger.text` · `senderName` · `attachments` · `mentionNames` · `channelName` · `link`…; `service_event` ⇒ `trigger.payload.<khoá>` theo danh mục của `eventType` (tham số, hoặc đọc từ cấu hình của `automationId`).

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDquerykhông—
triggerTypestringquerykhông—
automationIdGUIDquerykhông—
stepIdGUIDquerykhông—
eventTypestringquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/merge-fields" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "fields": [
      {
        "example": "…",
        "label": "…",
        "token": "…"
      }
    ],
    "label": "…",
    "scope": "…",
    "stepId": "0190a3c2-5b1e-7c3d-8e4f-000000000001"
  }
]
GET/api/v1/office/automations/quota

Hạn mức lượt chạy tháng của công ty

`{ month: "yyyy-MM" (giờ VN), used, limit, percent }`. Một lượt = một lần luật được kích hoạt (lượt con của vòng lặp không tính). Vượt 100% ⇒ lượt mới bị bỏ qua, nhật ký ghi lý do `quota_exceeded`; thao tác dữ liệu của người dùng không bị lỗi.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/quota" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "limit": 1,
  "month": "…",
  "percent": 1.5,
  "used": 1
}
GET/api/v1/office/automations/service-events

Danh mục sự kiện của phần mềm khác (kích hoạt service_event)

`[{ service, label, events: [{ code, label, requiresFilter, perMinuteCap, keys: [{ key, label, type, token }] }] }]` — phần mềm → sự kiện → khoá dữ liệu (nhãn tiếng Việt). `code` đi vào `eventType` của cấu hình KHI; `key` đi vào `filters.groups[].rules[].key`; `token` là biến chèn được (`trigger.payload.<khoá>`). `type`: text · number · date · datetime · id · boolean. Danh mục này chính là danh sách sự kiện hệ thống đang nhận — luật có `eventType` không còn ở đây là `event_unknown` (không bật lại được).

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/service-events" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "events": [
      {
        "code": "…",
        "keys": [
          {
            "key": null,
            "label": null,
            "token": null,
            "type": null
          }
        ],
        "label": "…",
        "perMinuteCap": 1,
        "requiresFilter": true
      }
    ],
    "label": "…",
    "service": "…"
  }
]
GET/api/v1/office/automations/suggestions

Gợi ý tự động hoá riêng cho công ty (tab Gợi ý)

Tối đa 3 thẻ `[{ kind, triggerType, actionType, tableId, tableName, fieldId, fieldName, offsetDays, evidenceCount, evidenceDays, existingAutomationId, existingAutomationName, existingStatus, existingRuns, existingFailed }]` dựng từ dữ liệu thật: `date_expiring` = cột Ngày tên kiểu "Ngày hết hạn" có dòng tới hạn trong 30 ngày tới (mời luật "Khi tới ngày", 30 ngày trước); `busy_table` = bảng nhiều dòng mới 30 ngày qua mà chưa luật nào nghe. Có `existingAutomationId` = công ty đã có luật này (kèm số lượt/số hỏng 30 ngày qua). Máy chủ chỉ trả mã + số, câu chữ do giao diện dịch. Chỉ đọc.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/suggestions" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
  }
]
GET/api/v1/office/automations/summary

Số đếm cho Trung tâm tự động hoá

`{ total, active, inactive, mine, byTrigger: { [mã kích hoạt]: n }, archived, failing }` — `inactive` = mọi luật không Active; `archived` ⊂ `inactive`; `failing` = luật có lượt lỗi 7 ngày qua.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/summary" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "active": 1,
  "archived": 1,
  "byTrigger": {
    "key": 1
  },
  "failing": 1,
  "inactive": 1,
  "mine": 1,
  "total": 1
}
GET/api/v1/office/automations/{id}

Lấy 1 automation (kèm steps)

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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"
}
GET/api/v1/office/automations/{id}/diagnosis

Chẩn đoán: vì sao luật chạy / không chạy

Các phép kiểm theo thứ tự (`status` · `trigger` · `steps` · `quota` · `recent_failures`), `canRun` = không phép kiểm chặn nào hỏng, 5 lần BỎ QUA gần nhất kèm lý do đã dịch, và lần hỏng gần nhất. Chỉ đọc.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>/diagnosis" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
}
GET/api/v1/office/automations/{id}/overlaps

Luật khác cùng kích hoạt và cùng làm việc này

Các luật ĐANG BẬT khác của công ty có cùng kiểu kích hoạt, cùng phạm vi nghe (bảng, cột, loại sự kiện, kênh — bỏ phần lọc) và ít nhất một loại hành động chung với luật này, kèm `sharedActions`. Chỉ cảnh báo: bộ lọc khác nhau thì hai luật có thể không bao giờ cùng chạy, người dùng tự xét. Tối đa 10.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>/overlaps" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "name": "…",
    "sharedActions": [
      "…"
    ]
  }
]
GET/api/v1/office/automations/{id}/webhook/sample

Mẫu dữ liệu + cây khoá

`{ sample, sampleSource: listen|manual, sampleAt, listening, listenUntil, keys: [{ name, path: "trigger.payload.a.b", type, example, children }] }`. `path` chính là biến chèn vào cấu hình bước. Chưa có mẫu ⇒ sample null, keys [].

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/automations/<id>/webhook/sample" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
}
GET/api/v1/office/calendar-preferences

Thiết lập màn lịch của tôi

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendar-preferences" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "dayEndHour": 1,
  "dayStartHour": 1,
  "defaultEventMinutes": 1,
  "defaultView": "…",
  "showDeclined": true,
  "showWeekends": true,
  "timeZone": "…",
  "weekStartDay": 1
}
GET/api/v1/office/calendars

Lịch tôi đang đăng ký (cột trái)

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendars" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
  }
]
GET/api/v1/office/calendars/subscribable

Lịch có thể đăng ký thêm

Chỉ trả lịch người gọi THẬT SỰ được nhìn: lịch được chia sẻ và lịch ngày lễ.

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
termstringquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/calendars/subscribable" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
  }
]
GET/api/v1/office/connection-keys

Danh sách khoá đã cấp

KHÔNG bao giờ trả về khoá thật — chỉ có phần nhận diện `prefix`. `status` là MÃ: active · revoked.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/connection-keys" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
  }
]
GET/api/v1/office/dashboards/{id}/widgets/{widgetId}/data

Số liệu một ô, tính theo quyền người xem

unavailable = table_missing (bảng đã xoá) | no_access (ô đọc cột/bảng người xem không được thấy).

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—
widgetIdstringpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/dashboards/<id>/widgets/<widgetId>/data" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
}
GET/api/v1/office/events

Sự kiện trong một khoảng thời gian

Dùng cho lịch tuần và lịch tháng. Khoảng hỏi tối đa 120 ngày. eventType và status trả về là MÃ tiếng Anh. truncated=true nghĩa là danh sách bị cắt bởi trần an toàn (quá nhiều sự kiện hoặc quá nhiều lần lặp trong khung đang xem) — hẹp lại khoảng hỏi để xem đủ.

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
fromdatequerykhông—
todatequerykhông—
eventTypestringquerykhông—
mineOnlyboolquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/events" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/events/{id}

Chi tiết một sự kiện kèm người dự và phòng đã giữ

occurrenceStart là mốc GỐC của một lần trong chuỗi lặp — có kèm thì tiêu đề, giờ, mô tả, địa điểm trả về là bản ĐÃ ÁP ngoại lệ của đúng lần đó, không phải bản chung của cả chuỗi. Bỏ trống khi sự kiện không lặp, hoặc khi cần xem/sửa cả chuỗi (scope=all).

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—
occurrenceStartdatequerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/events/<id>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
}
GET/api/v1/office/events/{id}.ics

Tải tệp lịch .ics của sự kiện

Cho người TRONG công ty đã đăng nhập (chủ trì/người dự/lịch chia sẻ đủ mức). Khách ngoài công ty đi qua liên kết công khai riêng trong thư mời — xem PublicCalendarController, KHÔNG phải endpoint này.

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/events/<id>.ics" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
"…"
GET/api/v1/office/farm/device-controls

Danh sách phiếu lệnh

status: pending · dispatched · rejected · expired. scope: mine (phiếu tôi được duyệt) · all.

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
statusstringquerykhông—
scopestringquerykhông—
takeintquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/farm/device-controls" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
  }
]
GET/api/v1/office/farm/device-controls/emergency-stop

Trạng thái TẮT KHẨN điều khiển thiết bị tự động của trại

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Không có tham số.

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/farm/device-controls/emergency-stop" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "canChange": true,
  "changedAt": "2026-10-28T07:30:00Z",
  "changedBy": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "stopped": true
}
GET/api/v1/office/farm/device-controls/rules/{automationId}/approval

Trạng thái duyệt tự chạy của một luật

valid = dấu duyệt còn khớp luật và dữ liệu bảng (sửa luật / sửa lịch là mất hiệu lực).

Scope: office.automation.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
automationIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/farm/device-controls/rules/<automationId>/approval" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/meeting-minutes

Biên bản của một cuộc họp

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
eventIdGUIDquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/meeting-minutes" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
}
GET/api/v1/office/meeting-rooms

Danh sách phòng họp

minCapacity/equipment/building lọc ngay trong màn chọn phòng — equipment yêu cầu phòng có ĐỦ mọi mã đã hỏi.

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
activeOnlyboolquerykhông—
minCapacityintquerykhông—
equipmentobjectquerykhông—
buildingstringquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/meeting-rooms" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "autoReleaseMinutes": 1,
    "building": "…",
    "capacity": 1,
    "equipment": [
      "…"
    ],
    "floor": "…",
    "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "isActive": true,
    "location": "…",
    "maxBookingMinutes": 1,
    "name": "…",
    "requiresApproval": true
  }
]
GET/api/v1/office/meeting-rooms/{id}/busy-slots

Khung giờ bận của một phòng

Giao diện gọi ngay khi người dùng chọn phòng, để tô xám khung không chọn được.

Scope: office.calendar.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
idGUIDpathcó—
fromdatequerykhông—
todatequerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/meeting-rooms/<id>/busy-slots" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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"
  }
]
GET/api/v1/office/tables/{tableId}/fields

Liệt kê field của table

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/fields" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
  }
]
GET/api/v1/office/tables/{tableId}/fields/{fieldId}

Lấy chi tiết field

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
fieldIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/fields/<fieldId>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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": "…"
}
POST/api/v1/office/tables/{tableId}/records

Tạo record mới

Mobile ghi khi mất sóng: gửi kèm đầu X-Submission-Id (uuid máy sinh) + X-Captured-At (giờ ghi thật, ISO-8601). Gửi lại cùng mã ⇒ trả lại dòng đã có, không tạo trùng.

Scope: office.base.record.manageThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
datastringbodykhông—

Ví dụ

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 }'

Phản hồi mẫu

201 Created
null
POST/api/v1/office/tables/{tableId}/records/aggregate

Cộng gộp theo cột (tổng · trung bình · nhỏ nhất · lớn nhất · đếm)

Năm con số của thanh chân bảng, tính trên tập ĐANG LỌC — gửi kèm đúng bộ lọc mà lưới đang áp. Cộng ở máy chủ chứ không cộng trong lưới: lưới chỉ giữ vài trăm dòng quanh vùng cuộn, nên cộng những gì nó đang cầm sẽ cho ra con số NHẢY khi người dùng cuộn. Cột nằm ngoài phạm vi được xem bị loại khỏi kết quả. Không phải bộ máy công thức: không có cú pháp, không có vùng `A1:A10`, không lưu giá trị nào.

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
fieldIdsobjectbodykhông—
filterobjectbodykhông—

Ví dụ

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 } }'

Phản hồi mẫu

200 OK
[
  {
    "average": 1.5,
    "count": 1,
    "fieldId": "…",
    "max": 1.5,
    "min": 1.5,
    "numericCount": 1,
    "sum": 1.5
  }
]
POST/api/v1/office/tables/{tableId}/records/batch

Tạo nhiều record (tối đa 1000, all-or-nothing)

Scope: office.base.record.manageThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
recordsobjectbodykhông—

Ví dụ

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 ] }'

Phản hồi mẫu

201 Created
null
PUT/api/v1/office/tables/{tableId}/records/batch

Cập nhật nhiều record (tối đa 1000, all-or-nothing)

Scope: office.base.record.manageThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
itemsobjectbodykhông—

Ví dụ

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 } ] }'

Phản hồi mẫu

Tuyến này chưa khai schema phản hồi — gọi thử trong API Explorer để xem hình dạng.

POST/api/v1/office/tables/{tableId}/records/groups

Nhóm dòng: giá trị cột nhóm + số dòng, theo đúng thứ tự của records/list

Gửi CÙNG filter/sort/groupFieldId với records/list — lưới cộng dồn số dòng để đặt tiêu đề nhóm. Cột nhóm nằm ngoài quyền xem ⇒ fieldHidden=true, không có nhóm nào.

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
filterobjectbodykhông—
groupFieldIdstringbodykhông—
sortobjectbodykhông—

Ví dụ

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": "…" } ] }'

Phản hồi mẫu

200 OK
{
  "fieldHidden": true,
  "groups": [
    {
      "count": 1,
      "value": null
    }
  ],
  "tooMany": true,
  "total": 1
}
POST/api/v1/office/tables/{tableId}/records/list

Liệt kê record (phân trang + filter có cấu trúc trong body)

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
colorRulesobjectbodykhông—
filterobjectbodykhông—
groupFieldIdstringbodykhông—
pageintbodykhông—
pageSizeintbodykhông—
sortobjectbodykhông—

Ví dụ

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": "…" } ] }'

Phản hồi mẫu

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
}
GET/api/v1/office/tables/{tableId}/records/{recordId}

Lấy chi tiết record

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
recordIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/<recordId>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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"
}
PUT/api/v1/office/tables/{tableId}/records/{recordId}

Cập nhật record (merge mặc định; replace=true để ghi đè)

Gửi kèm `expectedValues` — bản đồ field_id → giá trị mà giao diện ĐANG HIỆN của đúng những ô đang sửa — để bật khoá lạc quan. Ô nào đã bị người khác đổi thì lời gọi trả **409** kèm danh sách ô xung đột và giá trị hiện tại của chúng, và **không ô nào được ghi**. Bỏ trống `expectedValues` thì không kiểm, đúng như nếp cũ — nên client đang chạy không đổi hành vi.

Scope: office.base.record.manageThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
recordIdGUIDpathcó—
datastringbodykhông—
expectedValuesstringbodykhông—
replaceboolbodykhông—

Ví dụ

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 }'

Phản hồi mẫu

Tuyến này chưa khai schema phản hồi — gọi thử trong API Explorer để xem hình dạng.

GET/api/v1/office/tables/{tableId}/records/{recordId}/history

Lịch sử sửa của record, tách theo từng ô (đã lọc theo quyền cột)

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
recordIdGUIDpathcó—
limitintquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/records/<recordId>/history" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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"
  }
]
GET/api/v1/office/tables/{tableId}/trash

Thùng rác — record đã xoá mềm của bảng (phân trang)

Chỉ record của công ty hiện tại; dữ liệu còn nguyên, có thể khôi phục hoặc xoá cứng.

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
pageintquerykhông—
pageSizeintquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/trash" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
}
GET/api/v1/office/tables/{tableId}/views

Liệt kê view của table

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "isPublic": true,
    "name": "…",
    "property": "…",
    "publicToken": "…",
    "tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "viewType": "…"
  }
]
GET/api/v1/office/tables/{tableId}/views/{viewId}

Lấy chi tiết view

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
viewIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views/<viewId>" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "id": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "isPublic": true,
  "name": "…",
  "property": "…",
  "publicToken": "…",
  "tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "viewType": "…"
}
GET/api/v1/office/tables/{tableId}/views/{viewId}/calendar-data

Record trong khoảng ngày của view kiểu Calendar

Ánh xạ trường ngày (startField/endField) trong property; from/to lọc theo ngày bắt đầu.

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
viewIdGUIDpathcó—
fromdatequerykhông—
todatequerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views/<viewId>/calendar-data" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
[
  {
    "data": "…",
    "end": "2026-10-28T07:30:00Z",
    "recordId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
    "start": "2026-10-28T07:30:00Z"
  }
]
GET/api/v1/office/tables/{tableId}/views/{viewId}/chart-data

Dữ liệu đã gộp của view kiểu Chart

Gộp theo cấu hình trong property (groupField + aggregation count/sum/avg). FE tự vẽ.

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
tableIdGUIDpathcó—
viewIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tables/<tableId>/views/<viewId>/chart-data" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "aggregation": "…",
  "buckets": [
    {
      "count": 1,
      "groupKey": "…",
      "value": 1.5
    }
  ],
  "groupField": "…",
  "valueField": "…"
}
GET/api/v1/office/tasks/monitor

Màn Theo dõi: sáu ô số liệu + bảng toàn đội + việc của từng người

Một lần gọi trả cả ba phần vì chúng đọc CÙNG một tập việc — tách ra thì ô số liệu và bảng bên dưới rơi vào hai thời điểm khác nhau và lệch số. elapsedMinutes là thời gian TRÔI QUA kể từ lúc bắt tay vào việc (started_at), KHÔNG phải giờ công. loadState: overloaded · normal · free. isExact=false nghĩa là công ty vượt trần số dòng nên mọi con số là ước lượng. taskListId thu hẹp MỌI con số vào một dự án — nó chỉ thu hẹp, không bao giờ cho thấy thêm việc mà scope vốn không cho thấy. Khi có taskListId, mỗi dòng thành viên mang thêm openCountAll = số việc mở của người đó trên toàn phạm vi. items của mỗi thành viên tối đa 200 (quá hạn trước); openTotal = tổng THẬT việc mở của người đó trong cùng phạm vi — so với số items để báo “đang hiện n/N”. dueSoonDays = cửa sổ “sắp đến hạn” đang áp (cạnh staleAfterDays).

Scope: office.task.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
scopestringquerykhông—
taskListIdGUIDquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tasks/monitor" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
  }
}
GET/api/v1/office/tasks/workload

Khối lượng theo người

isOverloaded so với ngưỡng quá tải, mặc định 10 việc đang mở; mỗi dòng trả kèm overloadThreshold = ngưỡng đang áp. Khối lượng CHỈ để tham khảo, không dùng tính tiến độ. taskListId thu hẹp vào một danh sách; listGroupId thu hẹp vào một thư mục (đội) GỒM mọi thư mục con. Có cả hai thì là GIAO. Danh sách/thư mục không tồn tại ⇒ 404.

Scope: office.task.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
taskListIdGUIDquerykhông—
listGroupIdGUIDquerykhông—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/tasks/workload" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

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
  }
]
GET/api/v1/office/views/{viewId}/location

Lần ngược từ mã khung nhìn lên bảng và ứng dụng chứa nó

Scope: office.base.record.viewThử trong API Explorer ▶

Tham số

Tham sốKiểuVị tríBắt buộcMô tả
viewIdGUIDpathcó—

Ví dụ

curl -X GET "https://api-prod.nextfarm.vn/api/v1/office/views/<viewId>/location" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Phản hồi mẫu

200 OK
{
  "appId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "appName": "…",
  "tableId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "tableName": "…",
  "viewId": "0190a3c2-5b1e-7c3d-8e4f-000000000001",
  "viewName": "…",
  "viewType": "…"
}