SuperAPI AI Directory

lark-base

Office & productivity

View repository

Updated 10-15 16:37

About this skill

Base

A regular Base is a data container, composed of a Base Block resource tree and Base-level configuration.folder、table、docx、dashboard、workflow are all Block types; Advanced Permission / Role is Base-level configuration and does not belong to Block. Table is the core Block among them that carries business data. Workspace is the outer container that organizes Base and BaseApp; BaseApp (AppMode) organizes Base data through Page and components, and is not an alias of Base.

Identity selection (preferred)

For Base operations, prefer --as user; when the user explicitly requests app identity, use --as bot. On permission failure, follow lark-shared to fix scope or resource ACL with the original identity; switch identity only when the user explicitly agrees to change the operator.

Must do before entering: resolve the target entity

Before starting operations, first determine base_token and the target entity type; if the context already provides the <bitable> / <base_refer> tag and resource ID, use them directly. Otherwise, choose the entry point by intent:

  1. URL or share link: lark-cli base +url-resolve --url '<url>' --as user. The Base URL enters the corresponding module based on the returned resource_type / block_type and coordinates such as table_id、view_id、record_id、dashboard_id、workflow_id、docx_token、share_token ; BaseApp /app/ URL returns app_token, and returns workspace_token and page_idwhen carried in the link. The entity type is based on the resolution result.
  2. Base title or keyword: lark-cli base +title-resolve --title '<keyword>' --as user. A single result directly obtains base_token; for multiple candidates, disambiguate by title, owner, and update time; if it still cannot be uniquely determined, ask the user to choose. Then locate the target entity according to the Base Block resource model below.
  3. Existing Base candidate list: When the user wants to list existing Base candidates and needs to filter/sort by dimensions such as recent access, owner, creator, time, type, switch to lark-cli drive +search --doc-types bitable --as user. To locate a single Base by title/keyword, still use +title-resolve. Common candidate list commands:
    • Recently accessed:lark-cli drive +search --doc-types bitable --sort open_time --opened-since 3m --page-size 20 --as user
    • Only list those I own: add --mine; if you want to list "those I created", use --created-by-me。
    • After obtaining the URL or token from the candidate item, use +url-resolve or +base-get to enter the Base business commands.
  4. BaseApp: Prefer using the real /app/ URL; when workspace_token is already available, use +workspace-entity-list --type baseapp to locate. If neither is available, ask the user to provide the app link or Workspace; do not globally guess app_token。

based on name.Read Base: For Base information, use +base-get; read the resource directory according to the Base Block resource model below.

Write Base: To create a new Base, use +base-create --name <base-name> --table-name <table-name> --fields '<field-array>' once to create the Base, first table, and fields simultaneously;+base-copy copy the entire Base; resources within a Base are uniformly managed according to the Block lifecycle below.

Base Template Center

The Template Center is a public Base template library, not an existing Base in the user's cloud space. When the user wants to create a new Base using a ready-made template and there is no anchor pointing to an existing object (no Base URL, no "my/recently accessed tables", and no specific existing Base name), you can read lark-base-template-center.md to find Template Center templates;+template-categories list public template categories,+template-list List public templates by category,+template-search Search public templates by business keywords.

Base Block resource model

Base
├── Base Block 资源树
│   ├── Table Block
│   │   ├── Field schema
│   │   ├── Records / CellValue
│   │   ├── Views
│   │   └── Forms / Questions
│   ├── Dashboard Block(布局容器)
│   │   └── Dashboard 内部 Blocks(图表、指标卡、文本)
│   ├── Workflow Block
│   │   └── Workflow definition(title、status、steps 执行图)
│   ├── Docx Block → docx_token / lark-doc
│   └── Folder Block → 子 Block
└── Base 级配置
    └── Advanced Permission / Roles

Every Base Block has id、type, a modifiable name, the parent_idof the Folder it is in, and an order within the same-level directory.+base-block-list is the unified discovery entry point;+base-block-create creates a Block,+base-block-rename modifies the name,+base-block-move via --parent-id adjusts the directory and via --before-id / --after-id adjusts the order,+base-block-delete deletes the Block. Type-specific content is then handled by the corresponding module commands.

When the type-specific initial content is already clear at creation time, you can complete it directly in one go using the corresponding construction command: for Table use +table-create --fields, for Dashboard use +dashboard-create to set the theme, for Workflow use +workflow-create --json to submit the complete definition; Folder and Docx use +base-block-create。

A Block's id directly serves as the corresponding module coordinate by type:

Block type Module coordinates and internal content
table id is table_id; internally contains Field, Record, View, and Form
dashboard id is dashboard_id; internally contains Dashboard components such as charts, metric cards, and text
workflow id is workflow_id; internally contains title, status, and steps execution graph
docx A Block additionally has docx_token; the body is handled by lark-doc Processing
folder id is the directory Block ID, and can also serve as --parent-id; only organizes child Blocks

Table Block(The Core)

Table itself is a Base Block and is also Base's core data storage layer; Field, Record, View, and Form are internal objects of Table, not Base Blocks. Business data queries, writes, associations, statistics, and analysis all start from Table. First use +table-list to locate the Table; ordinary reads where the field names and targets are known can go directly to Record commands, and only tasks that depend on field types/schema, such as writes, filtering, or associations, need to add +field-list. For multiple tables, +field-list can be executed concurrently. Basic Record / CellValue reads and writes follow the paths below directly; reference only carries advanced analysis, the complete protocol, and boundary details.

Read Table: +table-list locates the table,+table-get reads the details. Table-specific copy uses +table-copy, and async status uses +table-copy-status; schema and records are operated on by the internal objects below.

Most updates under Table take effect through an asynchronous pipeline, so reading immediately after a successful API return may temporarily not show the latest state. Prioritize the successful write response as the operation result; when a task must confirm the final state, first complete all related changes in the current round, then read them together for acceptance, avoiding reading back immediately after each individual write.

Field

Field defines the column schema.field_id is a stable column identifier,name is a modifiable display name; Formula, Lookup, Link, Select, etc. belong to Field types or capabilities.

Read Field: +field-list / +field-get / +field-search-options。Write Field: When creating multiple fields in an existing Table, prefer passing an array of field objects to a single +field-create --json ; for single-field updates and deletions use +field-update / +field-delete. Read field-create / field-updatefor creation and update respectively, and the command documentation continues to route Field JSON, Formula, and Lookup protocols.字段插件 is used to extend basic field capabilities: trigger LLM generation based on the content of other fields in the same row, and write back to an existing target field; currently it is confirmed that the target field supports text, single select, and number, and before configuring or triggering, first read field-extension。

Record

A Record is a row of data in a Table, containing the CellValue of that record under each Field. The system record_id is a stable, non-empty, and unique primary key within the table; the Table's primary field is only a display field.

1. Read records or cells

  • Given several record_id:+record-get --record-id <id1> --record-id <id2>
  • Keyword search:+record-search --keyword <text> --search-field <field>; specify at least one search field.
  • Other reads:+record-list; structured conditions and sorting use --filter-json / --sort-json。

When the number of rows is large and server-side predicate pushdown is needed,--filter-json use tuple condition; the most common filtering and full date range syntax:

{
  "logic": "and", // 全部条件成立;任一条件成立改为 "or"
  "conditions": [
    ["状态", "intersects", ["进行中", "暂停"]], // Select 命中任一选项
    ["标题", "intersects", "urgent"], // 文本包含
    ["备注", "non_empty"], // 非空;判断为空改用 "empty",两者都不传 value
    ["金额", ">=", 100], // 数字比较;支持 ==、!=、>、>=、<、<=
    ["关联项目", "intersects", [{ "id": "recxxx" }]], // Link 包含目标记录
    ["业务日期", "==", "ExactDate(2026-08-07)"], // 具体一天:按 Base 时区匹配 2026-08-07 当天
    ["发生时间", ">", "ExactDate(2024-01-31 23:59:59.999)"], // 日期不支持 >=;用 > 前一天最后一毫秒表达含当天的下界
    ["发生时间", "<", "ExactDate(2024-03-01 00:00:00)"] // 2024 年 2 月范围上界:小于 3 月 1 日零点
  ]
}

For the complete operators and value structures of each field, read Filter condition structure。

All reads repeatedly pass --field-id for minimal field projection, and uniformly write to an NDJSON artifact:--format ndjson --output <path>.ndjson. Each line is a Record JSON, and the stdout summary contains records_count and has_more for pagination determination.

# Example: 行数较大时先筛选 Status 包含 Doing 的记录,再导出 20 条作为局部预览
lark-cli base +record-list \
  --base-token <base_token> --table-id <table_id> \
  --filter-json '{"logic":"and","conditions":[["Status","intersects",["Doing"]]]}' \
  --field-id Name --field-id Status --field-id Score --limit 20 \
  --format ndjson --output ./records-preview.ndjson --as user

PREVIEW_ROWS=5
head -n "$PREVIEW_ROWS" ./records-preview.ndjson
tail -n "$PREVIEW_ROWS" ./records-preview.ndjson

When the expected number of records is fewer than 500 rows, it is recommended not to do predicate pushdown and instead pull directly to local and process with jq or Python; when the number of rows is large, you can use --filter-json pushdown for expressible conditions; conditions that cannot be pushed down, such as regex and derived ones, continue to be processed locally.

# jq:对服务端筛选结果追加名称格式筛选,再投影必要字段
jq -c 'select((.Name // "") | test("^Task-[0-9]+$")) | {record_id, Name}' ./records-preview.ndjson

# Python:按行读取并做简单汇总
python3 - <<'PY'
import json

with open("records-preview.ndjson", encoding="utf-8") as stream:
    rows = (json.loads(line) for line in stream if line.strip())
    print(sum((row.get("Score") or 0) for row in rows))
PY

--limit 's default value is 2000, and the maximum value is 2000; usually there is no need to manually specify the limit parameter; supports --offset parameter; only when has_more=false and the query range matches the problem can it be treated as a complete result. For full reads of large tables, View range reads, complex JOINs, collections/multi-values, time series, semantic or professional statistical analysis, read Record Query and Analysis SOP。

2. Add records or update record cells

A Record is {字段名或 field_id: CellValue}, common CellValues:

{
  "标题": "Created from shortcut", // text: string
  "官网": "[官网](https://example.com)", // text(url): 裸 URL 或 Markdown link
  "联系电话": "13800000000", // text(phone): 合法电话号码字符串
  "邮箱": "owner@example.com", // text(email): 合法邮箱字符串
  "单选": ["Todo"], // select: array<string>;单选时数组最多一个值;
  "标签": ["高优", "外部依赖"], // 多选 select: array<string>;必须是当前字段存在的选项;
  "工时": 8, // number: double,不经过格式化的纯数字
  "带时区时间": "2026-03-24T10:00:00+08:00", // datetime:带时区,遵循传入的时区
  "不带时区时间": "2026-03-24 10:00", // datetime:不带时区,自动按当前 Base 时区转换
  "毫秒时间戳": 1774317600000, // datetime:也支持 Unix 毫秒时间戳
  "已完成": false, // checkbox: boolean
  "负责人": [{ "id": "ou_123" }], // user(multiple=false): 数组最多一个元素
  "协作人": [{ "id": "ou_123" }, { "id": "ou_456" }], // user(multiple=true): 数组可包含多个元素
  "群聊": [{ "id": "oc_123" }, { "id": "oc_456" }], // group_chat(multiple=true)
  "关联任务": [{ "id": "rec456" }], // link: array<{id}>,record_id 来自目标表
  "坐标": { "lng": 116.397428, "lat": 39.90923 }, // location: {lng,lat}
  "清空": null, // 清空单元格,传 null
  "清空数组": [] // 清空数组类单元格,空数组和 null 都可以
}

Attachments use dedicated shortcuts to upload, download, or remove. created_at, updated_at, created_by, updated_by, auto_number, formula, lookup type fields are read-only; if mistakenly written to a cell, it will return ignored_fields indicates these fields are silently filtered, and the remaining fields are written normally.

# 新增:成功时返回 record_id_list
lark-cli base +record-batch-create \
  --base-token <base_token> --table-id <table_id> \
  --json '{"create_records":[{"Name":"Task A","Status":["Todo"]},{"Name":"Task B","Score":20}]}' --as user

# 更新:每条记录只提交要改变的字段
lark-cli base +record-batch-update \
  --base-token <base_token> --table-id <table_id> \
  --json '{"update_records":{"<record_id_a>":{"Status":["Done"]},"<record_id_b>":{"Score":100}}}' --as user

For large payloads, you can use a script to generate json and then use --json @file.json. A single batch is at most 200 records; if exceeded, split into batches, and write serially to the same Table; parallelism may trigger 1254291 concurrency conflict errors.

3. Other Record operations

  • +record-delete --base-token <base_token> --table-id <table_id> --record-id <id1> --record-id <id2> Delete several records
  • +record-share-link-create --base-token <base_token> --table-id <table_id> --record-id <id1> --record-id <id2> Create a record share link
  • +record-history-list Query the change events of a single record, read History record protocol
  • Attachments must use +record-upload-attachment / +record-download-attachment / +record-remove-attachment operations.

View

View shares the underlying records of a Table; when there is no special display requirement, prefer using grid. To read an existing view, use +view-list / +view-get。

Before editing any View, you must read View types and lifecycle, including creation, renaming, configuration changes (filtering, sorting, grouping, field visibility, timeline, cards), and deletion. View selection, applicable configurations, and complete operation examples are unified in that reference.

Form

A Form is attached to a Table, uses Fields as questions, and each valid submission creates a Record; suitable for information collection, external filling, conditional questions, and attachment submission.

  1. Read the form configuration in a Table: use +form-list / +form-get to read forms, use +form-questions-list to read question configurations; these commands use the form's owning base_token + table_id。
  2. Create or modify the form configuration in a Table: use +form-create / +form-update / +form-delete Manage forms; questions are carried by Table Field, and question ID corresponds to field_id, creation and update respectively read questions create / questions update, deletion uses +form-questions-delete。
  3. Adjust form question visibility and order: Form in the visible_fields interface acts as a View,form_id passed to --view-id. Use +view-get-visible-fields to read the currently visible questions, then use +view-set-visible-fields to submit the complete ordered list of question IDs that should ultimately be displayed; omitting a currently visible question hides it, adding an existing hidden Form member redisplays it, and an empty list hides all questions. Targets can only include existing Form members; the visible_rule of a still-displayed question can only reference visible questions located before it.
  4. Manage form sharing: use +form-share-get / +form-share-update to manage enable/disable, access scope, and anonymous/login requirements; read the current state before updating, modify only one field at a time, and explicitly pass boolean values as true or false。
  5. Fill out and submit a shared form: for a form share link, use +url-resolve to obtain share_token, follow Form detail to execute +form-detail to read the actual questions, required fields, and display conditions, then follow Form submit to construct fields and attachments and execute +form-submit。

Relationship between form questions and fields:

  • +form-questions-create supports two forms: creating a new field question requires title + type; an existing field question requires use_existing_field:true + field_id. An existing field question merely adds that field to the form; it does not create a new field or change existing record data; do not carry field definition attributes such as type、style、options for this form.
  • Before creating a question, first +form-questions-list. If the target title already exists, unless the user explicitly requests an independent question with the same name, prefer to use +form-questions-update to modify the question configuration; do not first create a question with the same name and then delete the old question.
  • +form-questions-delete is a high-risk write operation. By default it deletes the underlying Field carrying the question and all record data for that field; if you only want to remove the question from the form while keeping the field/data, you must pass --keep-field. After keeping the field, you can use +form-questions-create --questions '[{"use_existing_field":true,"field_id":"<field_id>"}]' to add it back to the form.

Dashboard Block

Dashboard Block is the dashboard container in the Base Block tree, responsible for carrying the page theme, layout, and internal component collection; it itself does not represent any single chart's data. Use +dashboard-list to locate the container,+dashboard-get to read container information,+dashboard-update to modify the theme, and+dashboard-arrange to uniformly orchestrate the layout of internal components.

Manage Dashboard sharing: use +dashboard-share-get / +dashboard-share-update to manage enable/disable, access scope, and the entry for returning to the source Base; read the current state before updating, modify only one field at a time, and explicitly false will be preserved.

Components inside the container, such as charts, metric cards, and text, are also called Blocks in the Dashboard API, but they do not belong to the Base Block tree. Internal Blocks are divided into three operation paths:

  1. Read configuration: +dashboard-block-list / +dashboard-block-get read the component type, layout, and data_config; the body of a text component also belongs to the configuration.
  2. Write configuration: +dashboard-block-create / +dashboard-block-update / +dashboard-block-delete manage components,data_config define data sources, dimensions, metrics, aggregations, or text content.
  3. Read content: +dashboard-block-get-data read the calculation results of data components such as charts and metric cards.

Before operating on internal Blocks, first read Dashboard, and from that entry continue routing component configuration and result protocols.

Application mode and the Workspace mental model

A Workspace is the spatial container that organizes Bases and BaseApps; a BaseApp must belong to a Workspace when it is created. A BaseApp uses Pages to organize its interface, and each Page contains chart, list, or rich-text components; components reference Base data via data_config but do not change the ownership relationships of Bases, Tables, Fields, and Records. Workspace is responsible for resource ownership, App is responsible for pages and components, and Base is responsible for data.

  1. Workspace: use +workspace-create、+workspace-entity-list and +workspace-move-in to create directories, list the Bases/BaseApps within them, or move resources in.
  2. Application: use +app-create / +app-get; application queries and creation depend on the real app_token / workspace_token。
  3. Page: use +app-page-list/get/create/rename/delete to manage Pages.
  4. Component: use +app-block-list/get/create/update to read and write component configuration, and use +app-block-get-data to read component computation results.

Before starting a BaseApp, Workspace, Page, or component task, fully read application mode and Workspace; when constructing components data_config continue reading application component configuration. BaseApp does not go through lark-apps. Currently, BaseApp duplication, full Page duplication, page icons, and moving resources out of a Workspace are not supported; handle these goals according to the capability boundaries in the reference, and do not pass them off by creating empty objects or using Drive moves.

  • Pages and components in a BaseApp (application mode) use app_token / page_id / block_id, while tables, fields, and records still use the base_tokenof the Base referenced by the component; do not mix tokens or treat BaseApp as an alias for Base.
  • Reusing an existing BaseApp block's data_config can only serve as a structural template; before the first Create/Update, still align item by item with the user's explicit requirements; when the user requires sorting, you must explicitly write group_by[].sort.order or the top-level sort.order, and must not substitute the direction omitted by the old configuration or the current get-data result order.
  • An application page's block and a dashboard block are the same underlying entity, but their ID systems are not interchangeable; choose commands and configuration protocols according to the current module reference.

Workflow Block

A Workflow itself is a Base Block, and internally it is an execution graph of steps connected by next / children ; triggers, actions, conditional branches, and loops are all step types. It is suitable for scheduled execution, Record creation or change linkage, message notifications, record reads and writes, and cross-system calls. Workflow is divided into three operation paths:

  1. Reading configuration: +workflow-list locate the workflow,+workflow-get read title、status and the complete steps execution graph.
  2. Writing configuration: +workflow-create create the complete definition,+workflow-update update the complete definition; before constructing or modifying configuration, read Workflow, and from that entry point continue routing step types and schemas.
  3. Runtime state control: +workflow-enable / +workflow-disable enable or disable an existing Workflow without modifying the steps execution graph.

Advanced Permission(AdvPerm)

AdvPerm enables fine-grained permission mode for a Base; Role builds on this to configure access capabilities for resources such as Base, Table, View, Field, Record, Dashboard, and Docx, and is suitable for restricting visibility scope, editing capability, copy/download, and data access rules by team or responsibility.

Reading AdvPerm: +base-get view is_advanced,+role-list / +role-get view roles.Writing AdvPerm: +advperm-enable / +advperm-disable enable or disable advanced permissions,+role-create / +role-update / +role-delete Manage roles. First read Permissions and roles, and continue routing the permissions JSON protocol from this entry.

Docx Block

Docx Block is a Feishu document resource organized in a Base directory, suitable for placing descriptions, plans, and reports together with data tables, dashboards, and workflows in the same Base; the body still uses the standard Docx data model.

From the Base Block resource directory, locate the document by --type docx and obtain docx_token; reading, creating, and editing the body use lark-doc。

Folder Block

Folder Block only handles Base directory grouping and hierarchical organization. Use +base-block-list --parent-id <folder_block_id> to read direct child items.

General execution contract

  • Update first confirms whether the command is a full replacement or a delta: full replacement uses the trusted current configuration for read-modify-write, while delta submits only the target changes.
  • Prefer using the write return to confirm the result; read back the target only when the return is insufficient for confirmation or the task explicitly requires verification.
  • When the command has a confirmation gate, after confirming the target and impact use --yes。

Not within the scope of this Skill

  • Authentication, initialization, scope, identity switching, and authorization recovery → lark-shared
  • Excel、CSV、.base Import/export between local files and Base such as lark-drive; for online copy use +base-copy
  • Body editing of Base-embedded Docx → lark-doc; spreadsheet content operations → lark-sheets