@jinshuju/mcp 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,12 +15,14 @@
15
15
  {
16
16
  "name": "filters",
17
17
  "in": "query",
18
- "required": false
18
+ "required": false,
19
+ "json": true
19
20
  },
20
21
  {
21
22
  "name": "sort",
22
23
  "in": "query",
23
- "required": false
24
+ "required": false,
25
+ "json": true
24
26
  },
25
27
  {
26
28
  "name": "next",
@@ -67,12 +69,112 @@
67
69
  "description": "Fuzzy match on name (case-insensitive; matches both the public name and the in-product name). Accepts several values (`q[]=A&q[]=B`), matching forms whose name contains any of them. Equivalent to `filters=[{\"field\":\"form_name\",\"operator\":\"like\",\"value\":...}]`."
68
70
  },
69
71
  "filters": {
70
- "type": "string",
71
- "description": "Filters, a JSON array; conditions are combined with AND. Filterable fields and operators:\n| field | type | operators |\n|---|---|---|\n| `form_name` | text | `eq` `ne` `any_in` `none_in` `like` `not_like` |\n| `created_at` | time | `eq` `ne` `gte` `gt` `lte` `lt` `within_last` |\n| `last_entry_created_at` | time | same as above (forms that have never received an entry have no value) |\n| `entries_count` | integer | `eq` `ne` `gte` `gt` `lte` `lt` |\n\nThe value of `within_last` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month), meaning the window going back from now.\nExample: `[{\"field\":\"last_entry_created_at\",\"operator\":\"within_last\",\"value\":{\"unit\":\"day\",\"n\":7}}]`\n"
72
+ "type": [
73
+ "array",
74
+ "string"
75
+ ],
76
+ "items": {
77
+ "type": "object",
78
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
79
+ "required": [
80
+ "operator"
81
+ ],
82
+ "properties": {
83
+ "field": {
84
+ "type": "string",
85
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
86
+ },
87
+ "api_code": {
88
+ "type": "string",
89
+ "deprecated": true,
90
+ "description": "Deprecated alias of `field`; use `field`."
91
+ },
92
+ "trigger": {
93
+ "type": "string",
94
+ "deprecated": true,
95
+ "description": "Deprecated alias of `field`; use `field`."
96
+ },
97
+ "operator": {
98
+ "type": "string",
99
+ "enum": [
100
+ "eq",
101
+ "ne",
102
+ "any_in",
103
+ "none_in",
104
+ "between",
105
+ "not_between",
106
+ "null",
107
+ "not_null",
108
+ "gte",
109
+ "gt",
110
+ "lte",
111
+ "lt",
112
+ "like",
113
+ "not_like",
114
+ "within_last",
115
+ "equal",
116
+ "not_equal",
117
+ "start",
118
+ "end"
119
+ ],
120
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
121
+ },
122
+ "value": {
123
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
124
+ }
125
+ }
126
+ },
127
+ "examples": [
128
+ [
129
+ {
130
+ "field": "entries_count",
131
+ "operator": "gte",
132
+ "value": 1
133
+ }
134
+ ]
135
+ ],
136
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND. Filterable fields and operators:\n| field | type | operators |\n|---|---|---|\n| `form_name` | text | `eq` `ne` `any_in` `none_in` `like` `not_like` |\n| `created_at` | time | `eq` `ne` `gte` `gt` `lte` `lt` `within_last` |\n| `last_entry_created_at` | time | same as above (forms that have never received an entry have no value) |\n| `entries_count` | integer | `eq` `ne` `gte` `gt` `lte` `lt` |\n\nThe value of `within_last` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month), meaning the window going back from now.\nExample: `[{\"field\":\"last_entry_created_at\",\"operator\":\"within_last\",\"value\":{\"unit\":\"day\",\"n\":7}}]`\n"
72
137
  },
73
138
  "sort": {
74
- "type": "string",
75
- "description": "Sort rules, a JSON array, each item `{\"field\": \"<field>\", \"order\": \"asc\"|\"desc\"}` (order defaults to asc), applied in order.\nSortable fields: `created_at`, `last_entry_created_at`, `entries_count`; any other field, an invalid order or unparseable JSON returns 400.\nWith `sort`, `next` becomes a cursor of the form `row:<offset>`, usable only in requests with the same `sort`; rows with equal values may change order between pages.\n"
139
+ "type": [
140
+ "array",
141
+ "string"
142
+ ],
143
+ "items": {
144
+ "type": "object",
145
+ "required": [
146
+ "field"
147
+ ],
148
+ "properties": {
149
+ "field": {
150
+ "type": "string",
151
+ "enum": [
152
+ "created_at",
153
+ "last_entry_created_at",
154
+ "entries_count"
155
+ ],
156
+ "description": "Form attribute to sort by"
157
+ },
158
+ "order": {
159
+ "type": "string",
160
+ "enum": [
161
+ "asc",
162
+ "desc"
163
+ ],
164
+ "default": "asc",
165
+ "description": "Sort direction"
166
+ }
167
+ }
168
+ },
169
+ "examples": [
170
+ [
171
+ {
172
+ "field": "last_entry_created_at",
173
+ "order": "desc"
174
+ }
175
+ ]
176
+ ],
177
+ "description": "Sort rules, an array of FormSortRule objects, applied in order.\nSortable fields: `created_at`, `last_entry_created_at`, `entries_count`; any other field, an invalid order or unparseable JSON returns 400.\nWith `sort`, `next` becomes a cursor of the form `row:<offset>`, usable only in requests with the same `sort`; rows with equal values may change order between pages.\n"
76
178
  },
77
179
  "next": {
78
180
  "type": "string",
@@ -107,7 +209,7 @@
107
209
  {
108
210
  "operationId": "getForm",
109
211
  "summary": "Show a form's structure",
110
- "description": "Show a form's structure\nReturns the form's name, public fill URL (`url`), description, field definitions and settings. Each element of `fields` is a single-key object `{ \"<api_code>\": {...} }`, in field order.\nThe following are included when the matching parameter is `true`:\n- `include_analytics`: each analysable field's definition carries `analytics`;\n- `include_theme`: carries `theme` (the form theme);\n- `include_field_rules`: carries `field_rules` (field display rules);\n- `include_extended_attributes`: carries `extended_attributes` (source-tracking links);\n- `include_transactions`: carries `transactions` (payment statistics) when the form is bound to a payment account.\nReturns schema \"FormDetail\" (see get_schema).\nThe api_code of each field in the returned fields is its key when reading and writing entries.",
212
+ "description": "Show a form's structure\nReturns the form's name, `kind`, `scene`, public URL (`url`), description, field definitions and settings. Each element of `fields` is a single-key object `{ \"<api_code>\": {...} }`, in field order.\nAlso answers for a table or a quick payment form token; `kind` says which it is.\nThe following are included when the matching parameter is `true`:\n- `include_analytics`: each analysable field's definition carries `analytics`;\n- `include_theme`: carries `theme` (the form theme);\n- `include_field_rules`: carries `field_rules` (field display rules);\n- `include_extended_attributes`: carries `extended_attributes` (source-tracking links);\n- `include_transactions`: carries `transactions` (payment statistics) when the form is bound to a payment account.\nReturns schema \"FormDetail\" (see get_schema).\nThe api_code of each field in the returned fields is its key when reading and writing entries.",
111
213
  "tag": "Forms",
112
214
  "method": "get",
113
215
  "path": "/forms/{form_token}",
@@ -206,7 +308,7 @@
206
308
  {
207
309
  "operationId": "createForm",
208
310
  "summary": "Create a form",
209
- "description": "Create a form\nCreates a form from a list of field definitions and returns the full form structure. `name` and `fields` are required.\n- `scene` sets the form's scene; exam / evaluation question types (such as `SingleSelect`, `FillInBlank`) can only be used in the scenes that support them.\n- `layout=card` (paged) does not support PageBreak, Matrix*, TableField, GoodsField, ESignatureField, FormAssociation, MultipleBlanksField or any kind of Widget field.\n- The folder named by `folder_token` must be manageable and of kind form; otherwise returns 404 / 400 respectively.\n- `setting` accepts only whitelisted keys (see `FormSettingWriteInput`); `setting.notification_rules` replaces, as a whole, the notification rules created through the API.\n- The returned form structure carries `url` (the public fill URL).\nReturns schema \"Form\" (see get_schema).\nEach item of fields branches on type: get_schema(\"FieldInput\") lists the types, then get_schema(\"<Type>Input\") (e.g. \"TextFieldInput\") shows the properties that type accepts; do not guess field properties. For an exam or evaluation form use create_exam_form / create_evaluation_form.",
311
+ "description": "Create a form\nCreates a form from a list of field definitions and returns the full form structure. `name` and `fields` are required.\n- `scene` sets the form's scene; exam / evaluation question types (such as `SingleSelect`, `FillInBlank`) can only be used in the scenes that support them.\n- `layout=card` (paged) does not support PageBreak, Matrix*, TableField, GoodsField, ESignatureField, FormAssociation, MultipleBlanksField or any kind of Widget field.\n- The folder named by `folder_token` must be manageable and of kind form; otherwise returns 404 / 400 respectively.\n- `setting` accepts only whitelisted keys (see `FormSettingWriteInput`); `setting.notification_rules` replaces, as a whole, the notification rules created through the API.\n- The returned form structure carries `url` (the public fill URL).\nReturns schema \"Form\" (see get_schema).\nEach item of fields branches on type: get_schema(\"FieldInput\") maps each type to its schema in x-variants (TextField → \"TextFieldInput\", SingleSelect → \"SingleSelectInput\"), and get_schema on that name shows the properties that type accepts; do not guess field properties or schema names. For an exam or evaluation form use create_exam_form / create_evaluation_form.",
210
312
  "tag": "Forms",
211
313
  "method": "post",
212
314
  "path": "/forms",
@@ -702,6 +804,11 @@
702
804
  "folder_token": {
703
805
  "type": "string",
704
806
  "description": "Target folder token or id; when omitted, the copy is not put in a folder"
807
+ },
808
+ "with_notification_rules": {
809
+ "type": "boolean",
810
+ "default": false,
811
+ "description": "Copy the notification rules too; takes manage permission on the source form, and copies none when the caller is outside the source form creator's account"
705
812
  }
706
813
  },
707
814
  "additionalProperties": false,
@@ -716,6 +823,60 @@
716
823
  "openWorldHint": false
717
824
  }
718
825
  },
826
+ {
827
+ "operationId": "deleteForm",
828
+ "summary": "Delete a form",
829
+ "description": "Delete a form\nMoves the form and its entries to the trash, from which the product can restore it; on success, returns the form token.",
830
+ "tag": "Forms",
831
+ "method": "delete",
832
+ "path": "/forms/{form_token}",
833
+ "params": [
834
+ {
835
+ "name": "form_token",
836
+ "in": "path",
837
+ "required": true
838
+ }
839
+ ],
840
+ "paramNames": [
841
+ "form_token"
842
+ ],
843
+ "successStatus": 200,
844
+ "scopes": [
845
+ "forms"
846
+ ],
847
+ "name": "delete_form",
848
+ "title": "Delete a form",
849
+ "inputSchema": {
850
+ "type": "object",
851
+ "properties": {
852
+ "form_token": {
853
+ "type": "string",
854
+ "description": "Form token (`token` from `GET /forms`); a 24-character hexadecimal form id is also accepted."
855
+ }
856
+ },
857
+ "additionalProperties": false,
858
+ "required": [
859
+ "form_token"
860
+ ]
861
+ },
862
+ "outputSchema": {
863
+ "type": "object",
864
+ "required": [
865
+ "token"
866
+ ],
867
+ "properties": {
868
+ "token": {
869
+ "type": "string"
870
+ }
871
+ }
872
+ },
873
+ "annotations": {
874
+ "readOnlyHint": false,
875
+ "destructiveHint": true,
876
+ "idempotentHint": true,
877
+ "openWorldHint": false
878
+ }
879
+ },
719
880
  {
720
881
  "operationId": "moveFormToFolder",
721
882
  "summary": "Move a form into a folder",
@@ -934,7 +1095,8 @@
934
1095
  {
935
1096
  "name": "checks",
936
1097
  "in": "query",
937
- "required": true
1098
+ "required": true,
1099
+ "json": true
938
1100
  }
939
1101
  ],
940
1102
  "paramNames": [
@@ -956,8 +1118,63 @@
956
1118
  "description": "Form token (`token` from `GET /forms`); a 24-character hexadecimal form id is also accepted."
957
1119
  },
958
1120
  "checks": {
959
- "type": "string",
960
- "description": "Targets to check, a JSON array (1 to 100 items), each item one field or one choice:\n| Key | Type | Description |\n|---|---|---|\n| `field_api_code` | string | Required. api_code of the field to check; to check one column of a table field / matrix field, pass that column's api_code and also pass `parent_field` |\n| `choice_value` | string | Optional. To check only one choice, pass that choice's api_code; omitted, checks whether the whole field has any data |\n| `choice_type` | string | Optional, used with `choice_value`: `choice` (default), `statement` / `dimension` for matrix fields, `level_1` to `level_4` for cascading drop-downs |\n| `parent_field` | string | Optional. When checking one column of a matrix / table field, the api_code of the parent field |\n| `check_extended_text` | boolean | Optional. When `true`, checks whether the choice's \"Other\" extra text has any data |\n| `goods_item_dimension_options` | object | Optional. When checking one spec of a goods field, the mapping of spec dimensions to options |\n"
1121
+ "type": [
1122
+ "array",
1123
+ "string"
1124
+ ],
1125
+ "items": {
1126
+ "type": "object",
1127
+ "required": [
1128
+ "field_api_code"
1129
+ ],
1130
+ "properties": {
1131
+ "field_api_code": {
1132
+ "type": "string",
1133
+ "description": "api_code of the field to check; to check one column of a table / matrix field, that column's api_code, with `parent_field` set"
1134
+ },
1135
+ "choice_value": {
1136
+ "type": "string",
1137
+ "description": "api_code of one choice to check; omitted, checks whether the whole field has any data"
1138
+ },
1139
+ "choice_type": {
1140
+ "type": "string",
1141
+ "enum": [
1142
+ "choice",
1143
+ "statement",
1144
+ "dimension",
1145
+ "level_1",
1146
+ "level_2",
1147
+ "level_3",
1148
+ "level_4"
1149
+ ],
1150
+ "description": "What `choice_value` names, `choice` by default; `statement` / `dimension` for matrix fields, `level_1` to `level_4` for cascading drop-downs"
1151
+ },
1152
+ "parent_field": {
1153
+ "type": "string",
1154
+ "description": "api_code of the parent field when checking one column of a matrix / table field"
1155
+ },
1156
+ "check_extended_text": {
1157
+ "type": "boolean",
1158
+ "description": "When true, checks whether the choice's \"Other\" extra text has any data"
1159
+ },
1160
+ "goods_item_dimension_options": {
1161
+ "type": "object",
1162
+ "description": "When checking one spec of a goods field, the mapping of spec dimensions to options"
1163
+ }
1164
+ }
1165
+ },
1166
+ "examples": [
1167
+ [
1168
+ {
1169
+ "field_api_code": "field_1"
1170
+ },
1171
+ {
1172
+ "field_api_code": "field_3",
1173
+ "choice_value": "Yb2d"
1174
+ }
1175
+ ]
1176
+ ],
1177
+ "description": "Targets to check, an array of 1 to 100 FieldDataCheck objects, each naming one field or one choice."
961
1178
  }
962
1179
  },
963
1180
  "additionalProperties": false,
@@ -989,7 +1206,8 @@
989
1206
  {
990
1207
  "name": "checks",
991
1208
  "in": "query",
992
- "required": true
1209
+ "required": true,
1210
+ "json": true
993
1211
  }
994
1212
  ],
995
1213
  "paramNames": [
@@ -1011,8 +1229,46 @@
1011
1229
  "description": "Form token (`token` from `GET /forms`); a 24-character hexadecimal form id is also accepted."
1012
1230
  },
1013
1231
  "checks": {
1014
- "type": "string",
1015
- "description": "Type conversions to preview, a JSON array (1 to 20 items), one field per item:\n| Key | Type | Description |\n|---|---|---|\n| `field_api_code` | string | Required. api_code of the field to convert |\n| `target_type` | string | Required. Target field type; see `GET /field_types` for values (`GET /field_types?kind=table` for tables) |\n| `target_precision` | string | Optional. When the target is `DateTimeField`, the date precision the edit will use (`month` / `day` / `minute` / `second`), so the preview matches the actual conversion; ignored otherwise |\n"
1232
+ "type": [
1233
+ "array",
1234
+ "string"
1235
+ ],
1236
+ "items": {
1237
+ "type": "object",
1238
+ "required": [
1239
+ "field_api_code",
1240
+ "target_type"
1241
+ ],
1242
+ "properties": {
1243
+ "field_api_code": {
1244
+ "type": "string",
1245
+ "description": "api_code of the field to convert"
1246
+ },
1247
+ "target_type": {
1248
+ "type": "string",
1249
+ "description": "Target field type; see `GET /field_types` for the values (`GET /field_types?kind=table` for tables)"
1250
+ },
1251
+ "target_precision": {
1252
+ "type": "string",
1253
+ "enum": [
1254
+ "month",
1255
+ "day",
1256
+ "minute",
1257
+ "second"
1258
+ ],
1259
+ "description": "When the target is `DateTimeField`, the date precision the edit will use, so the preview matches the actual conversion; ignored otherwise"
1260
+ }
1261
+ }
1262
+ },
1263
+ "examples": [
1264
+ [
1265
+ {
1266
+ "field_api_code": "field_1",
1267
+ "target_type": "RadioButton"
1268
+ }
1269
+ ]
1270
+ ],
1271
+ "description": "Type conversions to preview, an array of 1 to 20 FieldTypeChangeCheck objects, one field per item."
1016
1272
  }
1017
1273
  },
1018
1274
  "additionalProperties": false,
@@ -1103,12 +1359,14 @@
1103
1359
  {
1104
1360
  "name": "fields",
1105
1361
  "in": "query",
1106
- "required": false
1362
+ "required": false,
1363
+ "array": true
1107
1364
  },
1108
1365
  {
1109
1366
  "name": "filters",
1110
1367
  "in": "query",
1111
- "required": false
1368
+ "required": false,
1369
+ "json": true
1112
1370
  },
1113
1371
  {
1114
1372
  "name": "keyword",
@@ -1118,7 +1376,8 @@
1118
1376
  {
1119
1377
  "name": "sort",
1120
1378
  "in": "query",
1121
- "required": false
1379
+ "required": false,
1380
+ "json": true
1122
1381
  },
1123
1382
  {
1124
1383
  "name": "created_at",
@@ -1173,12 +1432,84 @@
1173
1432
  "description": "Form token (`token` from `GET /forms`); a 24-character hexadecimal form id is also accepted."
1174
1433
  },
1175
1434
  "fields": {
1176
- "type": "string",
1435
+ "type": [
1436
+ "array",
1437
+ "string"
1438
+ ],
1439
+ "items": {
1440
+ "type": "string"
1441
+ },
1177
1442
  "description": "Return only these fields. A JSON array, a comma-separated string or a repeated parameter, of field api_codes; the serial number is always returned. Returns 400 listing the available fields when an api_code is unknown."
1178
1443
  },
1179
1444
  "filters": {
1180
- "type": "string",
1181
- "description": "Filters, a JSON array of `{\"field\": \"<api_code>\", \"operator\": \"<op>\", \"value\": ...}` items (`field` can also be written as `api_code` / `trigger`); conditions are combined with AND.\n- All operators: `eq` `ne` `any_in` `none_in` `between` `not_between` `null` `not_null` `gte` `gt` `lte` `lt` `like` `not_like` `within_last`,\n aliases `equal` / `not_equal` / `start` (=gte) / `end` (=lte). Each field type accepts only some of them; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
1445
+ "type": [
1446
+ "array",
1447
+ "string"
1448
+ ],
1449
+ "items": {
1450
+ "type": "object",
1451
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
1452
+ "required": [
1453
+ "operator"
1454
+ ],
1455
+ "properties": {
1456
+ "field": {
1457
+ "type": "string",
1458
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
1459
+ },
1460
+ "api_code": {
1461
+ "type": "string",
1462
+ "deprecated": true,
1463
+ "description": "Deprecated alias of `field`; use `field`."
1464
+ },
1465
+ "trigger": {
1466
+ "type": "string",
1467
+ "deprecated": true,
1468
+ "description": "Deprecated alias of `field`; use `field`."
1469
+ },
1470
+ "operator": {
1471
+ "type": "string",
1472
+ "enum": [
1473
+ "eq",
1474
+ "ne",
1475
+ "any_in",
1476
+ "none_in",
1477
+ "between",
1478
+ "not_between",
1479
+ "null",
1480
+ "not_null",
1481
+ "gte",
1482
+ "gt",
1483
+ "lte",
1484
+ "lt",
1485
+ "like",
1486
+ "not_like",
1487
+ "within_last",
1488
+ "equal",
1489
+ "not_equal",
1490
+ "start",
1491
+ "end"
1492
+ ],
1493
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
1494
+ },
1495
+ "value": {
1496
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
1497
+ }
1498
+ }
1499
+ },
1500
+ "examples": [
1501
+ [
1502
+ {
1503
+ "field": "field_3",
1504
+ "operator": "any_in",
1505
+ "value": [
1506
+ "选项 A",
1507
+ "选项 B"
1508
+ ]
1509
+ }
1510
+ ]
1511
+ ],
1512
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND.\n- Each field type accepts only some of the operators; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
1182
1513
  },
1183
1514
  "keyword": {
1184
1515
  "type": "string",
@@ -1186,8 +1517,40 @@
1186
1517
  "description": "Full-text keyword (at most 200 characters), fuzzy-matched across all searchable fields. Forms with more than 99999 entries and no analytics engine enabled do not support full-text search (returns 400), unless `creator_id` also restricts the submitter."
1187
1518
  },
1188
1519
  "sort": {
1189
- "type": "string",
1190
- "description": "Sort rules, a JSON array of `{\"api_code\": \"<api_code>\", \"order\": \"asc\"|\"desc\"}` items, applied in order, with ascending serial number appended automatically at the end.\nOnly sortable fields are allowed; otherwise returns 400 listing the sortable fields. With `sort`, `next` becomes a row offset.\n"
1520
+ "type": [
1521
+ "array",
1522
+ "string"
1523
+ ],
1524
+ "items": {
1525
+ "type": "object",
1526
+ "required": [
1527
+ "api_code"
1528
+ ],
1529
+ "properties": {
1530
+ "api_code": {
1531
+ "type": "string",
1532
+ "description": "api_code of the field to sort by; only sortable fields are allowed"
1533
+ },
1534
+ "order": {
1535
+ "type": "string",
1536
+ "enum": [
1537
+ "asc",
1538
+ "desc"
1539
+ ],
1540
+ "default": "asc",
1541
+ "description": "Sort direction"
1542
+ }
1543
+ }
1544
+ },
1545
+ "examples": [
1546
+ [
1547
+ {
1548
+ "api_code": "created_at",
1549
+ "order": "desc"
1550
+ }
1551
+ ]
1552
+ ],
1553
+ "description": "Sort rules, an array of SortRule objects, applied in order, with ascending serial number appended automatically at the end.\nOnly sortable fields are allowed; otherwise returns 400 listing the sortable fields. With `sort`, `next` becomes a row offset.\n"
1191
1554
  },
1192
1555
  "created_at": {
1193
1556
  "type": "string",
@@ -1283,7 +1646,8 @@
1283
1646
  {
1284
1647
  "name": "fields",
1285
1648
  "in": "query",
1286
- "required": false
1649
+ "required": false,
1650
+ "array": true
1287
1651
  },
1288
1652
  {
1289
1653
  "name": "include_labels",
@@ -1316,7 +1680,13 @@
1316
1680
  "description": "Entry serial number"
1317
1681
  },
1318
1682
  "fields": {
1319
- "type": "string",
1683
+ "type": [
1684
+ "array",
1685
+ "string"
1686
+ ],
1687
+ "items": {
1688
+ "type": "string"
1689
+ },
1320
1690
  "description": "Return only these fields. A JSON array, a comma-separated string or a repeated parameter, of field api_codes; the serial number is always returned. Returns 400 listing the available fields when an api_code is unknown."
1321
1691
  },
1322
1692
  "include_labels": {
@@ -1819,12 +2189,14 @@
1819
2189
  {
1820
2190
  "name": "metrics",
1821
2191
  "in": "query",
1822
- "required": false
2192
+ "required": false,
2193
+ "json": true
1823
2194
  },
1824
2195
  {
1825
2196
  "name": "dimensions",
1826
2197
  "in": "query",
1827
- "required": false
2198
+ "required": false,
2199
+ "json": true
1828
2200
  },
1829
2201
  {
1830
2202
  "name": "limit",
@@ -1834,7 +2206,8 @@
1834
2206
  {
1835
2207
  "name": "filters",
1836
2208
  "in": "query",
1837
- "required": false
2209
+ "required": false,
2210
+ "json": true
1838
2211
  },
1839
2212
  {
1840
2213
  "name": "keyword",
@@ -1865,12 +2238,94 @@
1865
2238
  "description": "Form token (`token` from `GET /forms`); a 24-character hexadecimal form id is also accepted."
1866
2239
  },
1867
2240
  "metrics": {
1868
- "type": "string",
1869
- "description": "Required. Metrics to compute, a JSON array of 1 to 20 items, each `{\"func\": \"<function>\", \"field\": \"<api_code>\"}`; returns 400 when missing or empty.\nThe available functions depend on the field (the field's `analytics.agg_funcs` is authoritative):\n| Field | Functions |\n|---|---|\n| All fields | `count` `count_non_empty` `count_empty` |\n| Text | adds `count_unique` |\n| Number | adds `count_unique` `sum` `avg` `min` `max` `stddev` `median` `p25` `p75` `p90` |\n| Date | adds `count_unique` `min` `max` |\n"
2241
+ "type": [
2242
+ "array",
2243
+ "string"
2244
+ ],
2245
+ "items": {
2246
+ "type": "object",
2247
+ "required": [
2248
+ "func",
2249
+ "field"
2250
+ ],
2251
+ "properties": {
2252
+ "func": {
2253
+ "type": "string",
2254
+ "enum": [
2255
+ "count",
2256
+ "count_non_empty",
2257
+ "count_empty",
2258
+ "count_unique",
2259
+ "sum",
2260
+ "avg",
2261
+ "min",
2262
+ "max",
2263
+ "stddev",
2264
+ "median",
2265
+ "p25",
2266
+ "p75",
2267
+ "p90"
2268
+ ],
2269
+ "description": "Aggregate function; the field's `analytics.agg_funcs` says which ones it supports"
2270
+ },
2271
+ "field": {
2272
+ "type": "string",
2273
+ "description": "api_code of the field to aggregate"
2274
+ }
2275
+ }
2276
+ },
2277
+ "examples": [
2278
+ [
2279
+ {
2280
+ "func": "sum",
2281
+ "field": "field_5"
2282
+ },
2283
+ {
2284
+ "func": "count",
2285
+ "field": "field_1"
2286
+ }
2287
+ ]
2288
+ ],
2289
+ "description": "Required. Metrics to compute, an array of 1 to 20 AggregateMetric objects; returns 400 when missing or empty.\nThe available functions depend on the field (the field's `analytics.agg_funcs` is authoritative):\n| Field | Functions |\n|---|---|\n| All fields | `count` `count_non_empty` `count_empty` |\n| Text | adds `count_unique` |\n| Number | adds `count_unique` `sum` `avg` `min` `max` `stddev` `median` `p25` `p75` `p90` |\n| Date | adds `count_unique` `min` `max` |\n"
1870
2290
  },
1871
2291
  "dimensions": {
1872
- "type": "string",
1873
- "description": "Fields to group by, a JSON array of at most 2 items, each `{\"field\": \"<api_code>\", \"bucket\": \"<granularity>\"}`.\nOnly fields whose `analytics.groupable` is true can be grouped by; a date field must have a `bucket` (`day` / `week` / `month`, in Beijing time, UTC+8), and a non-date field must not have a `bucket`.\n"
2292
+ "type": [
2293
+ "array",
2294
+ "string"
2295
+ ],
2296
+ "items": {
2297
+ "type": "object",
2298
+ "required": [
2299
+ "field"
2300
+ ],
2301
+ "properties": {
2302
+ "field": {
2303
+ "type": "string",
2304
+ "description": "api_code of the field to group by; only fields whose `analytics.groupable` is true"
2305
+ },
2306
+ "bucket": {
2307
+ "type": "string",
2308
+ "enum": [
2309
+ "day",
2310
+ "week",
2311
+ "month"
2312
+ ],
2313
+ "description": "Time granularity, required for a date field and not allowed on any other"
2314
+ }
2315
+ }
2316
+ },
2317
+ "examples": [
2318
+ [
2319
+ {
2320
+ "field": "field_3"
2321
+ },
2322
+ {
2323
+ "field": "created_at",
2324
+ "bucket": "month"
2325
+ }
2326
+ ]
2327
+ ],
2328
+ "description": "Fields to group by, an array of at most 2 AggregateDimension objects.\nOnly fields whose `analytics.groupable` is true can be grouped by; a date field must have a `bucket` (`day` / `week` / `month`, in Beijing time, UTC+8), and a non-date field must not have a `bucket`.\n"
1874
2329
  },
1875
2330
  "limit": {
1876
2331
  "type": "integer",
@@ -1878,8 +2333,74 @@
1878
2333
  "description": "Maximum number of groups returned when grouping. Defaults to 20, max 200 (larger values are treated as 200; values below 1 use the default). Ignored without grouping."
1879
2334
  },
1880
2335
  "filters": {
1881
- "type": "string",
1882
- "description": "Filters, a JSON array of `{\"field\": \"<api_code>\", \"operator\": \"<op>\", \"value\": ...}` items (`field` can also be written as `api_code` / `trigger`); conditions are combined with AND.\n- All operators: `eq` `ne` `any_in` `none_in` `between` `not_between` `null` `not_null` `gte` `gt` `lte` `lt` `like` `not_like` `within_last`,\n aliases `equal` / `not_equal` / `start` (=gte) / `end` (=lte). Each field type accepts only some of them; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
2336
+ "type": [
2337
+ "array",
2338
+ "string"
2339
+ ],
2340
+ "items": {
2341
+ "type": "object",
2342
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
2343
+ "required": [
2344
+ "operator"
2345
+ ],
2346
+ "properties": {
2347
+ "field": {
2348
+ "type": "string",
2349
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
2350
+ },
2351
+ "api_code": {
2352
+ "type": "string",
2353
+ "deprecated": true,
2354
+ "description": "Deprecated alias of `field`; use `field`."
2355
+ },
2356
+ "trigger": {
2357
+ "type": "string",
2358
+ "deprecated": true,
2359
+ "description": "Deprecated alias of `field`; use `field`."
2360
+ },
2361
+ "operator": {
2362
+ "type": "string",
2363
+ "enum": [
2364
+ "eq",
2365
+ "ne",
2366
+ "any_in",
2367
+ "none_in",
2368
+ "between",
2369
+ "not_between",
2370
+ "null",
2371
+ "not_null",
2372
+ "gte",
2373
+ "gt",
2374
+ "lte",
2375
+ "lt",
2376
+ "like",
2377
+ "not_like",
2378
+ "within_last",
2379
+ "equal",
2380
+ "not_equal",
2381
+ "start",
2382
+ "end"
2383
+ ],
2384
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
2385
+ },
2386
+ "value": {
2387
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
2388
+ }
2389
+ }
2390
+ },
2391
+ "examples": [
2392
+ [
2393
+ {
2394
+ "field": "field_3",
2395
+ "operator": "any_in",
2396
+ "value": [
2397
+ "选项 A",
2398
+ "选项 B"
2399
+ ]
2400
+ }
2401
+ ]
2402
+ ],
2403
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND.\n- Each field type accepts only some of the operators; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
1883
2404
  },
1884
2405
  "keyword": {
1885
2406
  "type": "string",
@@ -1915,7 +2436,8 @@
1915
2436
  {
1916
2437
  "name": "fields",
1917
2438
  "in": "query",
1918
- "required": false
2439
+ "required": false,
2440
+ "array": true
1919
2441
  },
1920
2442
  {
1921
2443
  "name": "include_overview",
@@ -1925,7 +2447,8 @@
1925
2447
  {
1926
2448
  "name": "filters",
1927
2449
  "in": "query",
1928
- "required": false
2450
+ "required": false,
2451
+ "json": true
1929
2452
  },
1930
2453
  {
1931
2454
  "name": "keyword",
@@ -1955,7 +2478,13 @@
1955
2478
  "description": "Form token (`token` from `GET /forms`); a 24-character hexadecimal form id is also accepted."
1956
2479
  },
1957
2480
  "fields": {
1958
- "type": "string",
2481
+ "type": [
2482
+ "array",
2483
+ "string"
2484
+ ],
2485
+ "items": {
2486
+ "type": "string"
2487
+ },
1959
2488
  "description": "Summarize only these fields: field api_codes, comma-separated (or repeat `fields[]=`), returned in the order given. Defaults to every analyzable field. Returns 400, listing the analyzable fields, when a field is not analyzable or the caller has no permission to read it."
1960
2489
  },
1961
2490
  "include_overview": {
@@ -1964,8 +2493,74 @@
1964
2493
  "description": "Whether to return `overview` (matching count and entries added today). Defaults to true."
1965
2494
  },
1966
2495
  "filters": {
1967
- "type": "string",
1968
- "description": "Filters, a JSON array of `{\"field\": \"<api_code>\", \"operator\": \"<op>\", \"value\": ...}` items (`field` can also be written as `api_code` / `trigger`); conditions are combined with AND.\n- All operators: `eq` `ne` `any_in` `none_in` `between` `not_between` `null` `not_null` `gte` `gt` `lte` `lt` `like` `not_like` `within_last`,\n aliases `equal` / `not_equal` / `start` (=gte) / `end` (=lte). Each field type accepts only some of them; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
2496
+ "type": [
2497
+ "array",
2498
+ "string"
2499
+ ],
2500
+ "items": {
2501
+ "type": "object",
2502
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
2503
+ "required": [
2504
+ "operator"
2505
+ ],
2506
+ "properties": {
2507
+ "field": {
2508
+ "type": "string",
2509
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
2510
+ },
2511
+ "api_code": {
2512
+ "type": "string",
2513
+ "deprecated": true,
2514
+ "description": "Deprecated alias of `field`; use `field`."
2515
+ },
2516
+ "trigger": {
2517
+ "type": "string",
2518
+ "deprecated": true,
2519
+ "description": "Deprecated alias of `field`; use `field`."
2520
+ },
2521
+ "operator": {
2522
+ "type": "string",
2523
+ "enum": [
2524
+ "eq",
2525
+ "ne",
2526
+ "any_in",
2527
+ "none_in",
2528
+ "between",
2529
+ "not_between",
2530
+ "null",
2531
+ "not_null",
2532
+ "gte",
2533
+ "gt",
2534
+ "lte",
2535
+ "lt",
2536
+ "like",
2537
+ "not_like",
2538
+ "within_last",
2539
+ "equal",
2540
+ "not_equal",
2541
+ "start",
2542
+ "end"
2543
+ ],
2544
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
2545
+ },
2546
+ "value": {
2547
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
2548
+ }
2549
+ }
2550
+ },
2551
+ "examples": [
2552
+ [
2553
+ {
2554
+ "field": "field_3",
2555
+ "operator": "any_in",
2556
+ "value": [
2557
+ "选项 A",
2558
+ "选项 B"
2559
+ ]
2560
+ }
2561
+ ]
2562
+ ],
2563
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND.\n- Each field type accepts only some of the operators; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
1969
2564
  },
1970
2565
  "keyword": {
1971
2566
  "type": "string",
@@ -2001,12 +2596,14 @@
2001
2596
  {
2002
2597
  "name": "form_tokens",
2003
2598
  "in": "query",
2004
- "required": false
2599
+ "required": false,
2600
+ "array": true
2005
2601
  },
2006
2602
  {
2007
2603
  "name": "filters",
2008
2604
  "in": "query",
2009
- "required": false
2605
+ "required": false,
2606
+ "json": true
2010
2607
  }
2011
2608
  ],
2012
2609
  "paramNames": [
@@ -2030,12 +2627,84 @@
2030
2627
  "description": "Search keyword (at most 200 characters); returns 400 when empty."
2031
2628
  },
2032
2629
  "form_tokens": {
2033
- "type": "string",
2630
+ "type": [
2631
+ "array",
2632
+ "string"
2633
+ ],
2634
+ "items": {
2635
+ "type": "string"
2636
+ },
2034
2637
  "description": "Tokens (ids also accepted) of the forms or tables to search, comma-separated (or repeat `form_tokens[]=`), at most 10 after deduplication. When omitted, every accessible form is searched."
2035
2638
  },
2036
2639
  "filters": {
2037
- "type": "string",
2038
- "description": "Filters on form attributes that narrow the search scope, a JSON array with the same syntax and fields as `filters` of `GET /forms` (`form_name` / `created_at` / `last_entry_created_at` / `entries_count`); conditions are combined with AND.\nWithout an `entries_count` condition, `entries_count > 0` is appended automatically.\n"
2640
+ "type": [
2641
+ "array",
2642
+ "string"
2643
+ ],
2644
+ "items": {
2645
+ "type": "object",
2646
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
2647
+ "required": [
2648
+ "operator"
2649
+ ],
2650
+ "properties": {
2651
+ "field": {
2652
+ "type": "string",
2653
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
2654
+ },
2655
+ "api_code": {
2656
+ "type": "string",
2657
+ "deprecated": true,
2658
+ "description": "Deprecated alias of `field`; use `field`."
2659
+ },
2660
+ "trigger": {
2661
+ "type": "string",
2662
+ "deprecated": true,
2663
+ "description": "Deprecated alias of `field`; use `field`."
2664
+ },
2665
+ "operator": {
2666
+ "type": "string",
2667
+ "enum": [
2668
+ "eq",
2669
+ "ne",
2670
+ "any_in",
2671
+ "none_in",
2672
+ "between",
2673
+ "not_between",
2674
+ "null",
2675
+ "not_null",
2676
+ "gte",
2677
+ "gt",
2678
+ "lte",
2679
+ "lt",
2680
+ "like",
2681
+ "not_like",
2682
+ "within_last",
2683
+ "equal",
2684
+ "not_equal",
2685
+ "start",
2686
+ "end"
2687
+ ],
2688
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
2689
+ },
2690
+ "value": {
2691
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
2692
+ }
2693
+ }
2694
+ },
2695
+ "examples": [
2696
+ [
2697
+ {
2698
+ "field": "last_entry_created_at",
2699
+ "operator": "within_last",
2700
+ "value": {
2701
+ "unit": "day",
2702
+ "n": 30
2703
+ }
2704
+ }
2705
+ ]
2706
+ ],
2707
+ "description": "Filters on form attributes that narrow the search scope, an array of ScopeCondition objects, with the same fields as `filters` of `GET /forms` (`form_name` / `created_at` / `last_entry_created_at` / `entries_count`); conditions are combined with AND.\nWithout an `entries_count` condition, `entries_count > 0` is appended automatically.\n"
2039
2708
  }
2040
2709
  },
2041
2710
  "additionalProperties": false,
@@ -2224,12 +2893,14 @@
2224
2893
  {
2225
2894
  "name": "fields",
2226
2895
  "in": "query",
2227
- "required": false
2896
+ "required": false,
2897
+ "array": true
2228
2898
  },
2229
2899
  {
2230
2900
  "name": "filters",
2231
2901
  "in": "query",
2232
- "required": false
2902
+ "required": false,
2903
+ "json": true
2233
2904
  },
2234
2905
  {
2235
2906
  "name": "keyword",
@@ -2282,12 +2953,84 @@
2282
2953
  "description": "Form token (`token` from `GET /my/forms`); a 24-character hexadecimal form id is also accepted."
2283
2954
  },
2284
2955
  "fields": {
2285
- "type": "string",
2956
+ "type": [
2957
+ "array",
2958
+ "string"
2959
+ ],
2960
+ "items": {
2961
+ "type": "string"
2962
+ },
2286
2963
  "description": "Return only these fields. A comma-separated string or an array parameter (`fields[]=`) of field api_codes; unknown or non-public fields are skipped. The serial number is always returned."
2287
2964
  },
2288
2965
  "filters": {
2289
- "type": "string",
2290
- "description": "Filters, a JSON array of `{\"field\": \"<api_code>\", \"operator\": \"<op>\", \"value\": ...}` items (`field` can also be written as `api_code` / `trigger`); conditions are combined with AND.\n- All operators: `eq` `ne` `any_in` `none_in` `between` `not_between` `null` `not_null` `gte` `gt` `lte` `lt` `like` `not_like` `within_last`,\n aliases `equal` / `not_equal` / `start` (=gte) / `end` (=lte). Each field type accepts only some of them; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
2966
+ "type": [
2967
+ "array",
2968
+ "string"
2969
+ ],
2970
+ "items": {
2971
+ "type": "object",
2972
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
2973
+ "required": [
2974
+ "operator"
2975
+ ],
2976
+ "properties": {
2977
+ "field": {
2978
+ "type": "string",
2979
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
2980
+ },
2981
+ "api_code": {
2982
+ "type": "string",
2983
+ "deprecated": true,
2984
+ "description": "Deprecated alias of `field`; use `field`."
2985
+ },
2986
+ "trigger": {
2987
+ "type": "string",
2988
+ "deprecated": true,
2989
+ "description": "Deprecated alias of `field`; use `field`."
2990
+ },
2991
+ "operator": {
2992
+ "type": "string",
2993
+ "enum": [
2994
+ "eq",
2995
+ "ne",
2996
+ "any_in",
2997
+ "none_in",
2998
+ "between",
2999
+ "not_between",
3000
+ "null",
3001
+ "not_null",
3002
+ "gte",
3003
+ "gt",
3004
+ "lte",
3005
+ "lt",
3006
+ "like",
3007
+ "not_like",
3008
+ "within_last",
3009
+ "equal",
3010
+ "not_equal",
3011
+ "start",
3012
+ "end"
3013
+ ],
3014
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
3015
+ },
3016
+ "value": {
3017
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
3018
+ }
3019
+ }
3020
+ },
3021
+ "examples": [
3022
+ [
3023
+ {
3024
+ "field": "field_3",
3025
+ "operator": "any_in",
3026
+ "value": [
3027
+ "选项 A",
3028
+ "选项 B"
3029
+ ]
3030
+ }
3031
+ ]
3032
+ ],
3033
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND.\n- Each field type accepts only some of the operators; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
2291
3034
  },
2292
3035
  "keyword": {
2293
3036
  "type": "string",
@@ -2378,7 +3121,8 @@
2378
3121
  {
2379
3122
  "name": "form_tokens",
2380
3123
  "in": "query",
2381
- "required": false
3124
+ "required": false,
3125
+ "array": true
2382
3126
  }
2383
3127
  ],
2384
3128
  "paramNames": [
@@ -2401,7 +3145,13 @@
2401
3145
  "description": "Search keyword (at most 200 characters), fuzzy-matched in the form's public searchable fields."
2402
3146
  },
2403
3147
  "form_tokens": {
2404
- "type": "string",
3148
+ "type": [
3149
+ "array",
3150
+ "string"
3151
+ ],
3152
+ "items": {
3153
+ "type": "string"
3154
+ },
2405
3155
  "description": "Search only these forms. Comma-separated form tokens, or an array parameter (`form_tokens[]=`)."
2406
3156
  }
2407
3157
  },
@@ -3286,12 +4036,14 @@
3286
4036
  {
3287
4037
  "name": "filters",
3288
4038
  "in": "query",
3289
- "required": false
4039
+ "required": false,
4040
+ "json": true
3290
4041
  },
3291
4042
  {
3292
4043
  "name": "sort",
3293
4044
  "in": "query",
3294
- "required": false
4045
+ "required": false,
4046
+ "json": true
3295
4047
  },
3296
4048
  {
3297
4049
  "name": "next",
@@ -3332,12 +4084,112 @@
3332
4084
  "description": "Fuzzy match on name (case-insensitive; matches both the public name and the in-product name). Accepts several values (`q[]=A&q[]=B`), matching forms whose name contains any of them. Equivalent to `filters=[{\"field\":\"form_name\",\"operator\":\"like\",\"value\":...}]`."
3333
4085
  },
3334
4086
  "filters": {
3335
- "type": "string",
3336
- "description": "Filters, a JSON array; conditions are combined with AND. Filterable fields and operators:\n| field | type | operators |\n|---|---|---|\n| `form_name` | text | `eq` `ne` `any_in` `none_in` `like` `not_like` |\n| `created_at` | time | `eq` `ne` `gte` `gt` `lte` `lt` `within_last` |\n| `last_entry_created_at` | time | same as above (forms that have never received an entry have no value) |\n| `entries_count` | integer | `eq` `ne` `gte` `gt` `lte` `lt` |\n\nThe value of `within_last` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month), meaning the window going back from now.\nExample: `[{\"field\":\"last_entry_created_at\",\"operator\":\"within_last\",\"value\":{\"unit\":\"day\",\"n\":7}}]`\n"
4087
+ "type": [
4088
+ "array",
4089
+ "string"
4090
+ ],
4091
+ "items": {
4092
+ "type": "object",
4093
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
4094
+ "required": [
4095
+ "operator"
4096
+ ],
4097
+ "properties": {
4098
+ "field": {
4099
+ "type": "string",
4100
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
4101
+ },
4102
+ "api_code": {
4103
+ "type": "string",
4104
+ "deprecated": true,
4105
+ "description": "Deprecated alias of `field`; use `field`."
4106
+ },
4107
+ "trigger": {
4108
+ "type": "string",
4109
+ "deprecated": true,
4110
+ "description": "Deprecated alias of `field`; use `field`."
4111
+ },
4112
+ "operator": {
4113
+ "type": "string",
4114
+ "enum": [
4115
+ "eq",
4116
+ "ne",
4117
+ "any_in",
4118
+ "none_in",
4119
+ "between",
4120
+ "not_between",
4121
+ "null",
4122
+ "not_null",
4123
+ "gte",
4124
+ "gt",
4125
+ "lte",
4126
+ "lt",
4127
+ "like",
4128
+ "not_like",
4129
+ "within_last",
4130
+ "equal",
4131
+ "not_equal",
4132
+ "start",
4133
+ "end"
4134
+ ],
4135
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
4136
+ },
4137
+ "value": {
4138
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
4139
+ }
4140
+ }
4141
+ },
4142
+ "examples": [
4143
+ [
4144
+ {
4145
+ "field": "entries_count",
4146
+ "operator": "gte",
4147
+ "value": 1
4148
+ }
4149
+ ]
4150
+ ],
4151
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND. Filterable fields and operators:\n| field | type | operators |\n|---|---|---|\n| `form_name` | text | `eq` `ne` `any_in` `none_in` `like` `not_like` |\n| `created_at` | time | `eq` `ne` `gte` `gt` `lte` `lt` `within_last` |\n| `last_entry_created_at` | time | same as above (forms that have never received an entry have no value) |\n| `entries_count` | integer | `eq` `ne` `gte` `gt` `lte` `lt` |\n\nThe value of `within_last` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month), meaning the window going back from now.\nExample: `[{\"field\":\"last_entry_created_at\",\"operator\":\"within_last\",\"value\":{\"unit\":\"day\",\"n\":7}}]`\n"
3337
4152
  },
3338
4153
  "sort": {
3339
- "type": "string",
3340
- "description": "Sort rules, a JSON array, each item `{\"field\": \"<field>\", \"order\": \"asc\"|\"desc\"}` (order defaults to asc), applied in order.\nSortable fields: `created_at`, `last_entry_created_at`, `entries_count`; any other field, an invalid order or unparseable JSON returns 400.\nWith `sort`, `next` becomes a cursor of the form `row:<offset>`, usable only in requests with the same `sort`; rows with equal values may change order between pages.\n"
4154
+ "type": [
4155
+ "array",
4156
+ "string"
4157
+ ],
4158
+ "items": {
4159
+ "type": "object",
4160
+ "required": [
4161
+ "field"
4162
+ ],
4163
+ "properties": {
4164
+ "field": {
4165
+ "type": "string",
4166
+ "enum": [
4167
+ "created_at",
4168
+ "last_entry_created_at",
4169
+ "entries_count"
4170
+ ],
4171
+ "description": "Form attribute to sort by"
4172
+ },
4173
+ "order": {
4174
+ "type": "string",
4175
+ "enum": [
4176
+ "asc",
4177
+ "desc"
4178
+ ],
4179
+ "default": "asc",
4180
+ "description": "Sort direction"
4181
+ }
4182
+ }
4183
+ },
4184
+ "examples": [
4185
+ [
4186
+ {
4187
+ "field": "last_entry_created_at",
4188
+ "order": "desc"
4189
+ }
4190
+ ]
4191
+ ],
4192
+ "description": "Sort rules, an array of FormSortRule objects, applied in order.\nSortable fields: `created_at`, `last_entry_created_at`, `entries_count`; any other field, an invalid order or unparseable JSON returns 400.\nWith `sort`, `next` becomes a cursor of the form `row:<offset>`, usable only in requests with the same `sort`; rows with equal values may change order between pages.\n"
3341
4193
  },
3342
4194
  "next": {
3343
4195
  "type": "string",
@@ -4368,7 +5220,7 @@
4368
5220
  {
4369
5221
  "operationId": "getCurrentUser",
4370
5222
  "summary": "Show the current user",
4371
- "description": "Show the current user\nReturns the user behind the current credential. With an account-level credential (no specific user), returns the account owner.",
5223
+ "description": "Show the current user\nReturns the user behind the current credential. With an account-level credential (no specific user), returns the account owner.\nReturns schema \"CurrentUser\" (see get_schema).",
4372
5224
  "tag": "Account",
4373
5225
  "method": "get",
4374
5226
  "path": "/me",
@@ -4386,64 +5238,6 @@
4386
5238
  "properties": {},
4387
5239
  "additionalProperties": false
4388
5240
  },
4389
- "outputSchema": {
4390
- "type": "object",
4391
- "required": [
4392
- "id",
4393
- "name",
4394
- "email",
4395
- "mobile",
4396
- "role",
4397
- "billing_account_id",
4398
- "created_at"
4399
- ],
4400
- "properties": {
4401
- "id": {
4402
- "type": "string",
4403
- "description": "User ID"
4404
- },
4405
- "name": {
4406
- "type": [
4407
- "string",
4408
- "null"
4409
- ],
4410
- "description": "Display name"
4411
- },
4412
- "email": {
4413
- "type": [
4414
- "string",
4415
- "null"
4416
- ],
4417
- "description": "Email"
4418
- },
4419
- "mobile": {
4420
- "type": [
4421
- "string",
4422
- "null"
4423
- ],
4424
- "description": "Mobile number"
4425
- },
4426
- "role": {
4427
- "type": "string",
4428
- "enum": [
4429
- "owner",
4430
- "admin",
4431
- "worker",
4432
- "outworker"
4433
- ],
4434
- "description": "Role in the account"
4435
- },
4436
- "billing_account_id": {
4437
- "type": "string",
4438
- "description": "ID of the account the user belongs to"
4439
- },
4440
- "created_at": {
4441
- "type": "string",
4442
- "format": "date-time",
4443
- "description": "Signed up at (UTC)"
4444
- }
4445
- }
4446
- },
4447
5241
  "annotations": {
4448
5242
  "readOnlyHint": true,
4449
5243
  "destructiveHint": false,
@@ -5004,7 +5798,7 @@
5004
5798
  {
5005
5799
  "operationId": "createForm",
5006
5800
  "summary": "Create a form",
5007
- "description": "Creates an online exam form (scene=exam, scored automatically). Use it, not create_form, when the user wants an exam, test or quiz; an evaluation such as a psychological test, ability assessment, self-assessment questionnaire or training feedback uses create_evaluation_form. Questions must use exam question types (SingleSelect / MultiSelect / TrueOrFalse / DropDownSelect / FillInBlank / ShortAnswer / FillInNumber), each with answers (the correct answer and its score; the default absolute mode has one correct answer and scores only a fully correct response). Creates the form first, then applies exam_setting; if the settings are rejected, the form already exists and the result says so.\nCreates a form from a list of field definitions and returns the full form structure. `name` and `fields` are required.\n- `scene` sets the form's scene; exam / evaluation question types (such as `SingleSelect`, `FillInBlank`) can only be used in the scenes that support them.\n- `layout=card` (paged) does not support PageBreak, Matrix*, TableField, GoodsField, ESignatureField, FormAssociation, MultipleBlanksField or any kind of Widget field.\n- The folder named by `folder_token` must be manageable and of kind form; otherwise returns 404 / 400 respectively.\n- `setting` accepts only whitelisted keys (see `FormSettingWriteInput`); `setting.notification_rules` replaces, as a whole, the notification rules created through the API.\n- The returned form structure carries `url` (the public fill URL).",
5801
+ "description": "Creates an online exam form (scene=exam, scored automatically). Use it, not create_form, when the user wants an exam, test or quiz; an evaluation such as a psychological test, ability assessment, self-assessment questionnaire or training feedback uses create_evaluation_form. Questions must use exam question types (SingleSelect / MultiSelect / TrueOrFalse / DropDownSelect / FillInBlank / ShortAnswer / FillInNumber), each with answers (the correct answer and its score; the default absolute mode has one correct answer and scores only a fully correct response). A question type's schema is the one FieldInput's x-variants names (SingleSelect → \"SingleSelectInput\"; see get_schema). Creates the form first, then applies exam_setting; if the settings are rejected, the form already exists and the result says so.\nCreates a form from a list of field definitions and returns the full form structure. `name` and `fields` are required.\n- `scene` sets the form's scene; exam / evaluation question types (such as `SingleSelect`, `FillInBlank`) can only be used in the scenes that support them.\n- `layout=card` (paged) does not support PageBreak, Matrix*, TableField, GoodsField, ESignatureField, FormAssociation, MultipleBlanksField or any kind of Widget field.\n- The folder named by `folder_token` must be manageable and of kind form; otherwise returns 404 / 400 respectively.\n- `setting` accepts only whitelisted keys (see `FormSettingWriteInput`); `setting.notification_rules` replaces, as a whole, the notification rules created through the API.\n- The returned form structure carries `url` (the public fill URL).",
5008
5802
  "tag": "Forms",
5009
5803
  "method": "post",
5010
5804
  "path": "/forms",
@@ -5573,7 +6367,7 @@
5573
6367
  {
5574
6368
  "operationId": "createForm",
5575
6369
  "summary": "Create a form",
5576
- "description": "Creates an evaluation form (scene=evaluation). Use it when the user wants an evaluation, psychological test, ability assessment, self-assessment questionnaire or training feedback; not create_form, and not create_exam_form (an exam with correct answers). A scored evaluation uses SingleSelect / MultiSelect / DropDownSelect / Rating / Nps: each question lists every choice with its score in answers and sets answer_setting_mode=relative (every choice scores, none is right or wrong; the default absolute accepts one correct answer and scores any other choice 0). Do not score with a regular choice field's calculable / operand_value. A feedback questionnaire uses regular fields (RatingField / MatrixScaleField / TextArea, etc.) without scores. Creates the form first, then applies evaluation_setting (the report after submission, comments by total score range, dimensions).\nCreates a form from a list of field definitions and returns the full form structure. `name` and `fields` are required.\n- `scene` sets the form's scene; exam / evaluation question types (such as `SingleSelect`, `FillInBlank`) can only be used in the scenes that support them.\n- `layout=card` (paged) does not support PageBreak, Matrix*, TableField, GoodsField, ESignatureField, FormAssociation, MultipleBlanksField or any kind of Widget field.\n- The folder named by `folder_token` must be manageable and of kind form; otherwise returns 404 / 400 respectively.\n- `setting` accepts only whitelisted keys (see `FormSettingWriteInput`); `setting.notification_rules` replaces, as a whole, the notification rules created through the API.\n- The returned form structure carries `url` (the public fill URL).",
6370
+ "description": "Creates an evaluation form (scene=evaluation). Use it when the user wants an evaluation, psychological test, ability assessment, self-assessment questionnaire or training feedback; not create_form, and not create_exam_form (an exam with correct answers). A scored evaluation uses SingleSelect / MultiSelect / DropDownSelect / Rating / Nps: each question lists every choice with its score in answers and sets answer_setting_mode=relative (every choice scores, none is right or wrong; the default absolute accepts one correct answer and scores any other choice 0). A question type's schema is the one FieldInput's x-variants names (SingleSelect → \"SingleSelectInput\"; see get_schema). Do not score with a regular choice field's calculable / operand_value. A feedback questionnaire uses regular fields (RatingField / MatrixScaleField / TextArea, etc.) without scores. Creates the form first, then applies evaluation_setting (the report after submission, comments by total score range, dimensions).\nCreates a form from a list of field definitions and returns the full form structure. `name` and `fields` are required.\n- `scene` sets the form's scene; exam / evaluation question types (such as `SingleSelect`, `FillInBlank`) can only be used in the scenes that support them.\n- `layout=card` (paged) does not support PageBreak, Matrix*, TableField, GoodsField, ESignatureField, FormAssociation, MultipleBlanksField or any kind of Widget field.\n- The folder named by `folder_token` must be manageable and of kind form; otherwise returns 404 / 400 respectively.\n- `setting` accepts only whitelisted keys (see `FormSettingWriteInput`); `setting.notification_rules` replaces, as a whole, the notification rules created through the API.\n- The returned form structure carries `url` (the public fill URL).",
5577
6371
  "tag": "Forms",
5578
6372
  "method": "post",
5579
6373
  "path": "/forms",
@@ -6051,7 +6845,8 @@
6051
6845
  {
6052
6846
  "name": "filters",
6053
6847
  "in": "query",
6054
- "required": false
6848
+ "required": false,
6849
+ "json": true
6055
6850
  },
6056
6851
  {
6057
6852
  "name": "keyword",
@@ -6086,8 +6881,74 @@
6086
6881
  "description": "A form token, or an array of up to 10 tokens to count several forms in one call"
6087
6882
  },
6088
6883
  "filters": {
6089
- "type": "string",
6090
- "description": "Filters, a JSON array of `{\"field\": \"<api_code>\", \"operator\": \"<op>\", \"value\": ...}` items (`field` can also be written as `api_code` / `trigger`); conditions are combined with AND.\n- All operators: `eq` `ne` `any_in` `none_in` `between` `not_between` `null` `not_null` `gte` `gt` `lte` `lt` `like` `not_like` `within_last`,\n aliases `equal` / `not_equal` / `start` (=gte) / `end` (=lte). Each field type accepts only some of them; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
6884
+ "type": [
6885
+ "array",
6886
+ "string"
6887
+ ],
6888
+ "items": {
6889
+ "type": "object",
6890
+ "description": "One filter condition. A `filters` parameter is the JSON text of an array of these, combined with AND; each endpoint says which fields and operators it takes.",
6891
+ "required": [
6892
+ "operator"
6893
+ ],
6894
+ "properties": {
6895
+ "field": {
6896
+ "type": "string",
6897
+ "description": "What to filter on; a field api_code for entries, or a form attribute such as `created_at` for form lists. Required unless the deprecated `api_code` or `trigger` is given instead."
6898
+ },
6899
+ "api_code": {
6900
+ "type": "string",
6901
+ "deprecated": true,
6902
+ "description": "Deprecated alias of `field`; use `field`."
6903
+ },
6904
+ "trigger": {
6905
+ "type": "string",
6906
+ "deprecated": true,
6907
+ "description": "Deprecated alias of `field`; use `field`."
6908
+ },
6909
+ "operator": {
6910
+ "type": "string",
6911
+ "enum": [
6912
+ "eq",
6913
+ "ne",
6914
+ "any_in",
6915
+ "none_in",
6916
+ "between",
6917
+ "not_between",
6918
+ "null",
6919
+ "not_null",
6920
+ "gte",
6921
+ "gt",
6922
+ "lte",
6923
+ "lt",
6924
+ "like",
6925
+ "not_like",
6926
+ "within_last",
6927
+ "equal",
6928
+ "not_equal",
6929
+ "start",
6930
+ "end"
6931
+ ],
6932
+ "description": "Comparison; `equal` / `not_equal` / `start` / `end` are aliases of `eq` / `ne` / `gte` / `lte`. Each field type accepts only some operators, and an unsupported one returns 400 listing the available ones."
6933
+ },
6934
+ "value": {
6935
+ "description": "Condition value; its type depends on the field and the operator: a two-element array `[min, max]` for `between` / `not_between`, `{\"unit\": \"day\", \"n\": 30}` for `within_last`, and no value for `null` / `not_null`."
6936
+ }
6937
+ }
6938
+ },
6939
+ "examples": [
6940
+ [
6941
+ {
6942
+ "field": "field_3",
6943
+ "operator": "any_in",
6944
+ "value": [
6945
+ "选项 A",
6946
+ "选项 B"
6947
+ ]
6948
+ }
6949
+ ]
6950
+ ],
6951
+ "description": "Filters, an array of ScopeCondition objects; conditions are combined with AND.\n- Each field type accepts only some of the operators; an unsupported one returns 400 listing the available operators.\n- For choice fields (single choice / multiple choice / drop-down / cascading drop-down), `value` can be a choice api_code or a choice label; a cascading drop-down also accepts a `level1-level2` path.\n- For `between` / `not_between`, `value` is a two-element array `[min, max]`; matrix / table fields need `{\"<column api_code>\": [min, max]}`.\n- `within_last` works only on date fields; `value` looks like `{\"unit\":\"day\",\"n\":30}` (unit can be minute / day / week / month).\n- `creator_id` is a special field that filters by submitter with `eq` (the value is a user id), and can appear only once.\n- `serial_number` is a special field that filters by serial number with `eq` / `any_in`; several conditions are intersected.\n- For a relation field (RelationField), the `value` of `any_in` / `none_in` is serial numbers of entries in the related table; returns 400 when a serial number does not exist.\n- With a `created_at` condition, results are sorted by creation time instead.\n- To find entries whose multiple-choice field contains a choice, use `any_in` (`none_in` to exclude); `eq` is not \"contains\": it matches only entries with exactly the same set of choices."
6091
6952
  },
6092
6953
  "keyword": {
6093
6954
  "type": "string",