Rename the skill directory and update all references (SKILL.md frontmatter name, AGENTS.md, design doc, install.sh). Git tracks this as a rename so history is preserved.
12 KiB
Tables, Fields, Records & Views
Complete guide for building table structures and working with data via the inkreach-teable CLI.
Quick Start
Minimal walkthrough — create a table with fields in one shot, then insert a record:
# 1. Create a "Tasks" table with 4 fields
inkreach-teable table create --name "Tasks" --base-id bseXXX \
--fields '[
{"name":"Title","type":"singleLineText"},
{"name":"Status","type":"singleSelect","options":{"choices":["Todo","Doing","Done"]}},
{"name":"Due Date","type":"date"},
{"name":"Est Hours","type":"number","options":{"formatting":{"precision":1}}}
]'
# 2. Insert a record
inkreach-teable record create --table-id tblXXX \
--fields '{"Title":"Ship sign-up flow","Status":"Doing","Due Date":"2025-06-15","Est Hours":3.5}'
# 3. Verify
inkreach-teable record get --table-id tblXXX
Tip
:
table create --fieldscreates the table AND all fields atomically. For existing tables, usefield create.
Tables
Create
inkreach-teable table create --name "<name>" [--base-id <id>] \
[--fields '<json>'] [--description <desc>]
| Flag | Required | Description |
|---|---|---|
--name |
yes | Display name (unique within base) |
--base-id |
no | Defaults to stored config |
--fields |
no | Array of field objects (see below) |
--description |
no | Optional description |
--fields format: JSON array of {name, type, [options], [description]} objects. Allowed types and aliases:
| Shorthand | Full type | Shorthand | Full type |
|---|---|---|---|
text, str |
singleLineText |
long |
longText |
num, int |
number |
check, bool |
checkbox |
sel, select |
singleSelect |
multi, tags |
multipleSelect |
date |
date |
rate, star |
rating |
user, person |
user |
file, attach |
attachment |
link, rel |
link |
rollup |
rollup |
formula |
formula |
auto |
autoNumber |
created |
createdTime |
modified |
lastModifiedTime |
createdBy |
createdBy |
modifiedBy |
lastModifiedBy |
button |
button |
condRollup |
conditionalRollup |
Compact shorthand (in --fields only): "name:type" string format:
inkreach-teable table create --name "Projects" --fields '["Name:text","Budget:num","Active:check"]'
With select options: "Status:sel:Todo,Doing,Done", "Tags:mul:Bug,Feature,UI"
Update & Delete
inkreach-teable table update <tableId> --name "<newName>" [--description <d>]
inkreach-teable table delete <tableId>
| Operation | Idempotent? | Notes |
|---|---|---|
update |
yes | Only changes name/description |
delete |
DESTRUCTIVE | Deletes all records + fields; irreversible |
List & Get
inkreach-teable table list [--base-id <id>]
inkreach-teable table get <tableId>
table get returns dbTableName — the internal SQL table name used in sql queries (e.g., SELECT * FROM "bseXXX"."tbl_abc").
Fields
Create
inkreach-teable field create --table-id <tid> --name "<name>" \
--type <type> [--options '<json>'] [--description <d>]
| Flag | Required | Notes |
|---|---|---|
--table-id |
yes | Target table |
--name |
yes | Field display name |
--type |
yes | Full type name or alias (see field-types.md) |
--options |
depends on type | JSON object; see type-specific shapes below |
--description |
no | Optional |
Type inference from name: when --type is omitted, the CLI infers from the field name:
| Name pattern | Inferred type | Name pattern | Inferred type |
|---|---|---|---|
status, priority, stage, category, type, level |
singleSelect |
tag, label |
multipleSelect |
description, notes, comment, content, body |
longText |
count, amount, price, quantity, total, age |
number |
rating, score, stars |
rating |
is*, has*, active, enabled, done, completed |
checkbox |
assignee, owner, user |
user |
attachment, file, image, photo, document |
attachment |
email |
singleLineText |
url, link (without table context) |
singleLineText |
created time / created |
createdTime |
last modified / updated |
lastModifiedTime |
created by, author |
createdBy |
modified by, updated by |
lastModifiedBy |
Options by type (most common):
| Type | Required options | Shape |
|---|---|---|
singleSelect / multipleSelect |
choices |
{"choices":["A","B","C"]} or {"choices":[{"name":"A","color":"blue"}]} — colors auto-assigned if omitted |
number |
none (defaults integer) | {"formatting":{"precision":2}} for decimal |
rating |
none (defaults max=5, star, yellow) | {"max":5,"icon":"star","color":"yellowBright"} |
date |
none | {"formatting":{"date":"YYYY-MM-DD","time":"None","timeZone":"UTC"}} |
link |
foreignTableId / foreignTableName |
{"foreignTableId":"tblXXX","relationship":"manyOne"} |
formula |
expression |
{"expression":"{fieldId}+{otherFieldId}"} |
rollup |
via --lookup-options |
See field-types.md |
button |
workflow |
{"label":"Click","color":"blue","workflow":{"id":"wflXXX"}} |
Name resolution: for link fields, use foreignTableName instead of foreignTableId — the CLI resolves it automatically:
inkreach-teable field create --table-id tblXXX --name "Project" --type link \
--options '{"foreignTableName":"Projects","relationship":"manyOne"}'
Update & Delete
inkreach-teable field update <fieldId> [--name "<n>"] [--options '<json>']
inkreach-teable field delete <fieldId>
| Detail | Rule |
|---|---|
--name only |
Convenience; for other props use --options |
--options merge |
Partial updates; omitted keys are preserved |
field delete |
Irreversible — all cell data in that field is lost |
Records
Get (read)
# All records (paginated)
inkreach-teable record get --table-id <tid> [--filter '<json>'] [--projection '<json>'] \
[--page-size <n>] [--page <n>] [--search <kw>]
# Single record by ID
inkreach-teable record get-one <recordId>
| Flag | Description |
|---|---|
--filter |
Filter expression: {"fieldId":{"operator":"value"}} |
--projection |
JSON array of field IDs to return: '["fldXXX","fldYYY"]' |
--page-size |
Records per page (default 100) |
--search |
Keyword search: "keyword" (auto-wraps to {"value":"keyword"}) |
--view-id |
Fetch in view order with view's filter/sort/group applied |
Create
# Single record
inkreach-teable record create --table-id <tid> --fields '<json>'
# Batch (up to 2000)
inkreach-teable record create --table-id <tid> --records '<json>'
--fields format (single): {"FieldName":"value","Another":"value"} — field names resolve automatically.
Value semantics:
| Value | Meaning |
|---|---|
"string" |
Normal value |
null |
Clear the cell |
"" (empty string) |
Skip (no change; update only) |
Important
:
""is skip, not clear. Usenullto empty a cell. For checkbox:true= checked,null= unchecked (NOTfalse).
--typecast: auto-converts human-readable values to internal IDs. Essential for user and link fields:
# Without typecast — must use IDs
inkreach-teable record create --table-id tblXXX --fields '{"Assignee":{"id":"usrXXX","title":"Alice"}}'
# With typecast — use display names
inkreach-teable record create --table-id tblXXX --fields '{"Assignee":"Alice"}' --typecast
--records format (batch): {"header":["Field1","Field2"],"records":[["val1","val2"],["val3","val4"]]}
Update
inkreach-teable record update --table-id <tid> --records '<json>'
--records format: [{"id":"recXXX","fields":{"FieldName":"newValue"}}] — array of {id, fields} objects. Batch up to 2000.
Record reordering: pass --order with viewId, anchorId, position:
inkreach-teable record update --table-id tblXXX \
--records '[{"id":"recXXX","fields":{}}]' \
--order '{"viewId":"viwXXX","anchorId":"recYYY","position":"before"}'
Delete
inkreach-teable record delete --table-id <tid> --record-ids "recA,recB,recC"
Max 1000 IDs per call. Irreversible.
Views
List & Get
inkreach-teable view list <tableId>
inkreach-teable view get <viewId>
Create
inkreach-teable view create --table-id <tid> --name "<name>" [--type <t>]
--type |
Description |
|---|---|
grid |
Default spreadsheet view |
kanban |
Board (requires a singleSelect/link grouping field) |
form |
Form input view |
gallery |
Card gallery |
calendar |
Calendar (requires a date field for grouping) |
Update (configure filters, sorts, grouping)
inkreach-teable view update <viewId> \
[--name "<n>"] \
[--filter '<json>'] \
[--sort '<json>'] \
[--group '<json>'] \
[--column-meta '<json>']
Filters: {"conjunction":"and","filterSet":[{"fieldId":"fldXXX","operator":"is","value":"Done"}]}
Sorts: [{"fieldId":"fldXXX","order":"asc"}]
Group: [{"fieldId":"fldXXX","order":"asc"}]
Column meta: controls visibility, width, order of fields in the view.
Delete
inkreach-teable view delete <viewId>
Deleting a view does NOT delete the table or its data — only the view configuration.
Value Formats Quick Reference
| Field Type | Value format | Notes |
|---|---|---|
singleLineText / longText |
"string" |
|
number |
42 or 3.14 |
Integer or float |
checkbox |
true / null |
NOT false for unchecked |
date |
"2025-06-15" or "2025-06-15T09:00:00.000Z" |
ISO 8601; "now" maps to current time |
singleSelect |
"Option Name" |
(string) |
multipleSelect |
["Tag A","Tag B"] |
(array of strings) |
rating |
3 |
Integer 1..max |
attachment |
[{"name":"f.png","token":"xxx"}] |
Always array of objects; update replaces all |
user |
{"id":"usrXXX","title":"Alice"} |
With --typecast: just "Alice" or "alice@example.com" |
link |
[{"id":"recXXX"}] |
With --typecast: just "Linked Record Name" |
formula / rollup / lookup |
Read-only | Cannot be set via record create/update |
autoNumber / createdBy / createdTime / lastModifiedTime / lastModifiedBy |
Auto-populated | Cannot be set manually |
button |
{"count":0} |
Read-only; incremented by button clicks |
Common Patterns
| User intent | Correct approach | Wrong approach |
|---|---|---|
| Create a table with fields | table create --fields '[...]' — one call |
Multiple field create calls (slower, more error-prone) |
| Use display names for linked records | record create --fields '{"Project":"Acme"}' --typecast |
Manually looking up recXXX IDs |
| Use email to assign user | record create --typecast --fields '{"Assignee":"alice@co.com"}' |
Looking up usrXXX IDs |
| Clear a cell | null in the fields object |
"" (which means skip!) |
| Update one field, leave others | --records '[{"id":"recXXX","fields":{"Status":"Done"}}]' |
Re-sending all fields (unnecessary, slower) |
| Fetch only 2 columns | record get --projection '["fldXXX","fldYYY"]' |
Fetching all fields (wastes bandwidth) |
| Find records by keyword | record get --search "keyword" |
record get then filtering manually |
| Add a select field with colored options | --options '{"choices":["A","B"]}' — colors auto |
Manually specifying color for every choice |
| Make a link field to another table | --type link --options '{"foreignTableName":"Target","relationship":"manyOne"}' |
Using IDs + manual lookup |
| Reorder records in a view | record update --order '{"viewId":...,"anchorId":...,"position":"before"}' |
Deleting and re-creating records |
| View data in kanban board | view create --type kanban then view update --group |
Creating special columns |
| Set datetime in a date field | "2025-06-15T14:30:00.000Z" |
"2025-06-15 14:30" (non-ISO; may be rejected) |
| Update attachments | Always pass the full array (replaces all) | Trying to add/remove individual attachments |
| Batch insert 500 records | One record create --records call |
500 separate record create calls |