Operate data, fields, views, and permissions through the Bitable API.
Base URL: https://open.feishu.cn/open-apis/bitable/v1
Authentication and Token Acquisition
From the feishu_skills root directory, execute the shared script:
TOKEN="$(./scripts/get_feishu_token.sh)"
Request headers uniformly use Authorization: Bearer ${TOKEN}。
If a business API returns an invalid token, expired token, or 401, force a refresh and then retry the original request only once:
TOKEN="$(./scripts/get_feishu_token.sh --force-refresh)"
Environment Variables:
FEISHU_APP_IDFEISHU_APP_SECRET
Local Cache: ./.feishu_token_cache.json(reuse directly if not expired, refresh 5 minutes in advance by default)
Key Parameters:
app_token: The string after/base/in the Bitable URLtable_id: Retrieved by calling the list API
Record Operations
| API | Endpoint | Description |
|---|---|---|
| Create Single | POST /apps/{app_token}/tables/{table_id}/records |
- |
| Batch Create | POST .../records/batch_create |
Up to 500 records, supports Upsert |
| Update | PUT .../records/{record_id} |
- |
| Batch Update | POST .../records/batch_update |
Up to 500 records |
| Batch Delete | POST .../records/batch_delete |
Up to 500 records |
| Query | POST .../records/search |
Supports filter/sort/pagination |
Paginated Query of All Records(up to 500 records at a time, loop until has_more: false):
page_token = None
all_records = []
while True:
body = {"page_size": 500}
if page_token:
body["page_token"] = page_token
resp = post(".../records/search", json=body)
all_records.extend(resp["data"]["items"])
if not resp["data"].get("has_more"):
break
page_token = resp["data"]["page_token"]
Request Example:
{
"fields": {
"名称": "测试",
"金额": 100,
"进度": 0.75,
"评分": 4,
"日期": 1770508800000,
"状态": "进行中",
"标签": ["重要", "紧急"],
"完成": true,
"负责人": [{"id": "ou_xxx"}],
"电话": "13800138000",
"链接": {"text": "官网", "link": "https://example.com"}
}
}
⚠️ Do not pass numbers as strings; dates must be 13-digit millisecond timestamps.
Field Type Formats
| type | ui_type | Chinese Name | Write Format | Example |
|---|---|---|---|---|
| 1 | Text | Multi-line Text | String | "办公用品" |
| 1 | String | "test@example.com" |
||
| 2 | Number | Number | Numeric Value | 100 |
| 2 | Currency | Currency | Numeric Value | 1280.50 |
| 2 | Progress | Progress | Numeric Value (0~1) | 0.25 (25%) |
| 2 | Rating | Rating | Numeric Value (1~5) | 3 |
| 3 | SingleSelect | Single Select | String | "支出" (option auto-created) |
| 4 | MultiSelect | Multi Select | String Array | ["餐饮","交通"] |
| 5 | DateTime | Date | Millisecond Timestamp | 1770508800000 |
| 7 | Checkbox | Checkbox | Boolean Value | true |
| 11 | User | Person | Object Array | [{"id":"ou_xxx"}] |
| 13 | Phone | Phone | String | "13800138000" |
| 15 | Url | Hyperlink | Object | {"text":"名称","link":"https://..."} |
| 17 | Attachment | Attachment | Object Array | [{"file_token":"xxx"}] |
| 18 | SingleLink | One-way Link | String Array | ["recuxxx"] |
| 21 | DuplexLink | Two-way Link | String Array | ["recuxxx"] |
| 22 | Location | Location | String | "116.397,39.903" |
API write not supported: Formula, Lookup Reference, Created Time, Modified By, Auto Number
Date Format Conversion:
import datetime
ts = int(datetime.datetime(2026, 2, 9).timestamp() * 1000)
# → 1770508800000
Field Management
| API | Endpoint | Description |
|---|---|---|
| Get Field List | GET .../fields |
Returns type and ui_name |
| Create Field | POST .../fields |
{"field_name":"新字段","type":1} |
| Update Field | PUT .../fields/{field_id} |
Modifying single select requires providing the complete property |
| Delete Field | DELETE .../fields/{field_id} |
- |
Formula Field Example:
{
"type": 20,
"field_name": "利润",
"property": {"formula_expression": "[营收]-[成本]"}
}
Link Field Example:
{
"type": 18,
"field_name": "关联客户",
"property": {"table_id": "tblXXX", "multiple": true}
}
Data Table Management
| API | Endpoint | Description |
|---|---|---|
| Create Base | POST /apps |
{"name":"数据库名称"} |
| List Tables | GET /apps/{app_token}/tables |
- |
| Add Table | POST /apps/{app_token}/tables |
{"table":{"name":"表名"}} |
| Batch Add Tables | POST .../tables/batch_create |
Up to 10 tables |
| Delete Table | DELETE .../tables/{table_id} |
- |
| Copy Table | POST .../tables/{table_id}/copy |
- |
⚠️ Permission Management (Important):
- Tables created via API are visible only to the bot by default
- After creation, you need to add users as collaborators:
POST /permissions/{app_token}/members
{
"member_type": "user",
"member_id": "ou_xxx",
"perm": "full_access"
}
- Permission types:
view/edit/full_access
View Management
| API | Endpoint | Description |
|---|---|---|
| List Views | GET .../tables/{table_id}/views |
- |
| Create View | POST .../tables/{table_id}/views |
{"view_name":"新视图","view_type":"grid"} |
| Delete View | DELETE .../views/{view_id} |
- |
View types: grid(Grid) / kanban(Kanban) / gallery(Gallery) / gantt(Gantt)
Permission Management
| API | Endpoint | Description |
|---|---|---|
| Create Collaborator | POST /apps/{app_token}/roles/{role_id}/members/batch_create |
- |
| Delete Collaborator | POST .../members/batch_delete |
- |
| Update Permissions | PUT /apps/{app_token}/roles/{role_id} |
- |
Role types: owner / editor / reader
⚠️ Non-existent API
/apps/:app_token/tables/:table_id/statistics This API does not exist, and the official Feishu documentation does not provide a statistics summary API.
If you need to calculate statistics (such as sum, count), it is recommended to:
- Use
POST .../records/searchto fetch all records and then calculate on the client side - Create in the Baseformula field(such as
SUM、COUNT) and then read the field value via API
Best Practices
- Prioritize batch operations(to reduce API calls)
- Field types must match strictly(to avoid write failures)
- Use millisecond timestamps for dates(Python:
int(datetime.timestamp() * 1000)) - Use link fields to implement relational capabilities
- Add users as collaborators immediately after creating a table(to avoid invisibility)
- Single-select fields automatically create options(just write the option text directly)
Test Verification
15 field types that have been verified through actual testing:
- Text, Progress, Multi-select, Single-select, Date, Checkbox, Phone, User, URL
- Email, Currency, Rating, Location, One-way Link, Two-way Link
Test table:https://jvbmlo28x0.feishu.cn/base/YdOpb47PvalSbQsHPyXc7LrNnUh