@zeyos/client 0.1.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.
- package/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +458 -0
- package/agents/README.md +66 -0
- package/agents/shared/business-app-benchmarks.md +111 -0
- package/agents/shared/zeyos-entity-map.md +142 -0
- package/agents/shared/zeyos-entity-reference.md +570 -0
- package/agents/shared/zeyos-query-patterns.md +89 -0
- package/agents/zeyos-account-intelligence/SKILL.md +34 -0
- package/agents/zeyos-account-intelligence/agents/openai.yaml +4 -0
- package/agents/zeyos-account-intelligence/references/workflows.md +84 -0
- package/agents/zeyos-billing-insights/SKILL.md +41 -0
- package/agents/zeyos-billing-insights/agents/openai.yaml +4 -0
- package/agents/zeyos-billing-insights/references/workflows.md +106 -0
- package/agents/zeyos-campaign-and-outreach/SKILL.md +44 -0
- package/agents/zeyos-campaign-and-outreach/agents/openai.yaml +4 -0
- package/agents/zeyos-campaign-and-outreach/references/workflows.md +100 -0
- package/agents/zeyos-collaboration-and-activity/SKILL.md +37 -0
- package/agents/zeyos-collaboration-and-activity/agents/openai.yaml +4 -0
- package/agents/zeyos-collaboration-and-activity/references/workflows.md +104 -0
- package/agents/zeyos-collections-and-dunning/SKILL.md +46 -0
- package/agents/zeyos-collections-and-dunning/agents/openai.yaml +4 -0
- package/agents/zeyos-collections-and-dunning/references/workflows.md +132 -0
- package/agents/zeyos-commerce-and-inventory/SKILL.md +38 -0
- package/agents/zeyos-commerce-and-inventory/agents/openai.yaml +4 -0
- package/agents/zeyos-commerce-and-inventory/references/workflows.md +101 -0
- package/agents/zeyos-mail-operations/SKILL.md +35 -0
- package/agents/zeyos-mail-operations/agents/openai.yaml +4 -0
- package/agents/zeyos-mail-operations/references/workflows.md +110 -0
- package/agents/zeyos-notes-and-sops/SKILL.md +31 -0
- package/agents/zeyos-notes-and-sops/agents/openai.yaml +4 -0
- package/agents/zeyos-notes-and-sops/references/workflows.md +85 -0
- package/agents/zeyos-platform-and-schema/SKILL.md +37 -0
- package/agents/zeyos-platform-and-schema/agents/openai.yaml +4 -0
- package/agents/zeyos-platform-and-schema/references/workflows.md +97 -0
- package/agents/zeyos-work-management/SKILL.md +45 -0
- package/agents/zeyos-work-management/agents/openai.yaml +4 -0
- package/agents/zeyos-work-management/references/workflows.md +148 -0
- package/docs/01-api-reference/01-data-retrieval.md +601 -0
- package/docs/01-api-reference/02-authentication.md +288 -0
- package/docs/01-api-reference/03-resources.md +270 -0
- package/docs/01-api-reference/04-schema.md +539 -0
- package/docs/01-api-reference/_category_.json +9 -0
- package/docs/02-javascript-client/01-getting-started.md +146 -0
- package/docs/02-javascript-client/02-authentication.md +287 -0
- package/docs/02-javascript-client/03-making-requests.md +572 -0
- package/docs/02-javascript-client/04-practical-guide.md +348 -0
- package/docs/02-javascript-client/_category_.json +9 -0
- package/docs/03-cli/01-getting-started.md +219 -0
- package/docs/03-cli/02-commands.md +407 -0
- package/docs/03-cli/03-configuration.md +220 -0
- package/docs/03-cli/_category_.json +9 -0
- package/docs/04-agent-workflows/00-coding-agents.md +35 -0
- package/docs/04-agent-workflows/01-agent-quickstart.md +147 -0
- package/docs/04-agent-workflows/02-agent-recipes.md +109 -0
- package/docs/04-agent-workflows/03-cli-coverage-and-escalation.md +65 -0
- package/docs/04-agent-workflows/_category_.json +9 -0
- package/docs/04-sample-apps/01-kanban.md +89 -0
- package/docs/04-sample-apps/02-crm.md +81 -0
- package/docs/04-sample-apps/03-dashboard.md +80 -0
- package/docs/04-sample-apps/_category_.json +9 -0
- package/docs/05-tutorials/00-application-developers.md +43 -0
- package/docs/05-tutorials/01-integration-architecture.md +60 -0
- package/docs/05-tutorials/02-build-your-own-zeyos-frontend.md +517 -0
- package/docs/05-tutorials/03-server-side-integrations.md +185 -0
- package/docs/05-tutorials/_category_.json +9 -0
- package/docs/intro.md +197 -0
- package/openapi/api.json +24308 -0
- package/openapi/auth.json +415 -0
- package/openapi/dbref.json +56223 -0
- package/openapi/oauth2.json +781 -0
- package/openapi/sdk.json +949 -0
- package/openapi/views.txt +642 -0
- package/package.json +49 -0
- package/samples/crm/README.md +28 -0
- package/samples/crm/index.html +327 -0
- package/samples/crm/js/api.js +208 -0
- package/samples/crm/js/auth.js +61 -0
- package/samples/crm/js/main.js +545 -0
- package/samples/crm/js/state.js +90 -0
- package/samples/crm/js/ui.js +51 -0
- package/samples/dashboard/README.md +28 -0
- package/samples/dashboard/index.html +280 -0
- package/samples/dashboard/js/api.js +197 -0
- package/samples/dashboard/js/auth.js +59 -0
- package/samples/dashboard/js/main.js +382 -0
- package/samples/dashboard/js/state.js +81 -0
- package/samples/dashboard/js/ui.js +48 -0
- package/samples/kanban/README.md +28 -0
- package/samples/kanban/index.html +263 -0
- package/samples/kanban/js/api.js +152 -0
- package/samples/kanban/js/auth.js +59 -0
- package/samples/kanban/js/constants.js +40 -0
- package/samples/kanban/js/kanban.js +246 -0
- package/samples/kanban/js/main.js +362 -0
- package/samples/kanban/js/modals.js +474 -0
- package/samples/kanban/js/settings.js +82 -0
- package/samples/kanban/js/state.js +118 -0
- package/samples/kanban/js/ui.js +49 -0
- package/scripts/generate-client.mjs +344 -0
- package/src/generated/operations.js +9772 -0
- package/src/generated/schema.js +8982 -0
- package/src/index.js +85 -0
- package/src/runtime/client.js +1208 -0
- package/src/runtime/error.js +29 -0
- package/src/runtime/http.js +174 -0
- package/src/runtime/request-shape.js +35 -0
- package/src/runtime/schema.js +206 -0
- package/src/runtime/suggest.js +74 -0
- package/src/runtime/token-store.js +105 -0
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_label: Data Retrieval
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Data Retrieval
|
|
6
|
+
|
|
7
|
+
The ZeyOS REST API provides a flexible query language for retrieving data from any resource endpoint. You can control exactly which fields are returned, apply composite filters, search by keyword, sort results, paginate through large datasets, expand JSON and binary columns, and access extended data fields.
|
|
8
|
+
|
|
9
|
+
:::info HTTP Method
|
|
10
|
+
All list operations use **POST** requests with a JSON body, not GET. This is because queries can include complex filters, field selections, and composite expressions that would be impractical as URL query parameters.
|
|
11
|
+
:::
|
|
12
|
+
|
|
13
|
+
## Field Selection
|
|
14
|
+
|
|
15
|
+
By default, list endpoints return all standard fields for a resource. Use the `fields` parameter to request only the columns you need, reducing payload size and improving performance.
|
|
16
|
+
|
|
17
|
+
### Array Form
|
|
18
|
+
|
|
19
|
+
Pass a simple array of field names to select specific columns:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"fields": ["ID", "name", "status", "priority"]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**JavaScript client:**
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
const result = await client.api.listTickets({
|
|
31
|
+
fields: ['ID', 'name', 'status', 'priority'],
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Object Form with Aliases
|
|
36
|
+
|
|
37
|
+
Use an object to rename fields in the response. Keys become the output names; values are the source field paths:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"fields": {
|
|
42
|
+
"Id": "ID",
|
|
43
|
+
"Name": "lastname",
|
|
44
|
+
"Nickname": "extdata.nickname",
|
|
45
|
+
"Address": "contact.address",
|
|
46
|
+
"Postalcode": "contact.postalcode",
|
|
47
|
+
"Town": "contact.city",
|
|
48
|
+
"SalesAgent": "assigneduser.name"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**JavaScript client:**
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
const result = await client.api.listAccounts({
|
|
57
|
+
fields: {
|
|
58
|
+
Id: 'ID',
|
|
59
|
+
Name: 'lastname',
|
|
60
|
+
Nickname: 'extdata.nickname',
|
|
61
|
+
Address: 'contact.address',
|
|
62
|
+
Postalcode: 'contact.postalcode',
|
|
63
|
+
Town: 'contact.city',
|
|
64
|
+
SalesAgent: 'assigneduser.name',
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Dot-Notation Joins
|
|
70
|
+
|
|
71
|
+
Use dot notation to access fields on related records without a separate request. You can discover available relationships in the [Schema Reference](./04-schema.md).
|
|
72
|
+
|
|
73
|
+
| Notation | Description |
|
|
74
|
+
|----------|-------------|
|
|
75
|
+
| `contact.city` | City field from the linked contact record |
|
|
76
|
+
| `contact.address` | Address from the linked contact |
|
|
77
|
+
| `contact.postalcode` | Postal code from the linked contact |
|
|
78
|
+
| `contact.country` | Country from the linked contact |
|
|
79
|
+
| `assigneduser.name` | Name of the assigned user |
|
|
80
|
+
| `account.lastname` | Last name (or company name) of the linked account |
|
|
81
|
+
| `project.name` | Name of the linked project |
|
|
82
|
+
|
|
83
|
+
### Extended Data Fields via Dot-Notation
|
|
84
|
+
|
|
85
|
+
Access custom fields stored in a record's `extdata` JSON column using the `extdata.` prefix in your field selection:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"fields": {
|
|
90
|
+
"Nickname": "extdata.nickname",
|
|
91
|
+
"Department": "extdata.department"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
:::info
|
|
97
|
+
Extended data fields are user-defined and may vary between ZeyOS instances. Whenever you create a new form field in ZeyOS, the field's value is stored in `extdata`. Check your instance configuration for available custom fields.
|
|
98
|
+
:::
|
|
99
|
+
|
|
100
|
+
## Filters
|
|
101
|
+
|
|
102
|
+
The `filter` parameter lets you restrict results using comparison operators, string-matching operators, and composite logical expressions.
|
|
103
|
+
|
|
104
|
+
:::tip JavaScript Client: use `filters` (plural)
|
|
105
|
+
The REST API parameter is named `filter` (singular), but the JavaScript client also accepts `filters` (plural). Use `filters` when working with the client — it correctly handles both simple fields and GIN-indexed foreign key fields like `project`, `ticket`, and `account`. See the [Practical Guide](../02-javascript-client/04-practical-guide.md#filter-vs-filters) for details.
|
|
106
|
+
:::
|
|
107
|
+
|
|
108
|
+
### Filter Syntax
|
|
109
|
+
|
|
110
|
+
Filters are expressed as an object where keys are field names and values define the match condition:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
filter = {
|
|
114
|
+
"field": "value",
|
|
115
|
+
"field2": {"=": "value"},
|
|
116
|
+
"field3": {"<": "value1", ">": "value2"},
|
|
117
|
+
"field4": {"IN": ["value1", "value2"]},
|
|
118
|
+
N: ["AND/OR/NOT", {...}, {...}]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Simple Equality
|
|
123
|
+
|
|
124
|
+
Pass a field name with a plain value for equality matching:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"filter": {
|
|
129
|
+
"status": 1,
|
|
130
|
+
"visibility": 0
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Comparison Operators
|
|
136
|
+
|
|
137
|
+
Use an object value with operator keys for more advanced comparisons:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"filter": {
|
|
142
|
+
"priority": {">=": 3},
|
|
143
|
+
"amount": {">": 100, "<": 1000}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The full set of comparison operators:
|
|
149
|
+
|
|
150
|
+
| Operator | Description |
|
|
151
|
+
|----------|-------------|
|
|
152
|
+
| `=` | Equal to |
|
|
153
|
+
| `!=` or `<>` | Not equal to |
|
|
154
|
+
| `<` | Less than |
|
|
155
|
+
| `<=` | Less than or equal to |
|
|
156
|
+
| `>` | Greater than |
|
|
157
|
+
| `>=` | Greater than or equal to |
|
|
158
|
+
| `IN` | Value is in the given set |
|
|
159
|
+
| `!IN` | Value is not in the given set |
|
|
160
|
+
|
|
161
|
+
**IN operator example:**
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"filter": {
|
|
166
|
+
"contact.country": {"IN": ["DE", "AT", "GB"]}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### String Operators
|
|
172
|
+
|
|
173
|
+
For string fields, additional pattern-matching operators are available:
|
|
174
|
+
|
|
175
|
+
| Operator | Description | Case Sensitive |
|
|
176
|
+
|----------|-------------|:-:|
|
|
177
|
+
| `~` | Matches regular expression | Yes |
|
|
178
|
+
| `~*` | Matches regular expression | No |
|
|
179
|
+
| `!~` | Does not match regular expression | Yes |
|
|
180
|
+
| `!~*` | Does not match regular expression | No |
|
|
181
|
+
| `~~` | LIKE (pattern match) | Yes |
|
|
182
|
+
| `~~*` | LIKE (pattern match) | No |
|
|
183
|
+
| `!~~` | NOT LIKE | Yes |
|
|
184
|
+
| `!~~*` | NOT LIKE | No |
|
|
185
|
+
|
|
186
|
+
:::tip
|
|
187
|
+
The `~` operators test regular expressions, while `~~` operators use SQL-style LIKE patterns. The `*` suffix makes any operator case-insensitive.
|
|
188
|
+
:::
|
|
189
|
+
|
|
190
|
+
### Composite Filters (AND, OR, NOT)
|
|
191
|
+
|
|
192
|
+
Combine multiple conditions using logical operators. Composite filters use **numbered keys** in the filter object to include logical groups alongside simple field conditions:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"filter": {
|
|
197
|
+
"visibility": 0,
|
|
198
|
+
"contact.country": {"IN": ["DE", "AT", "GB"]},
|
|
199
|
+
"2": ["OR",
|
|
200
|
+
{"lastmodified": {">": 1524472045}},
|
|
201
|
+
{"contact.lastmodified": {">": 1524472045}}
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
In this example:
|
|
208
|
+
- `"visibility": 0` is a simple equality filter.
|
|
209
|
+
- `"contact.country": {"IN": [...]}` uses the IN operator on a joined field.
|
|
210
|
+
- The key `"2"` contains an OR group: the record matches if either its own `lastmodified` or its contact's `lastmodified` exceeds the given timestamp.
|
|
211
|
+
|
|
212
|
+
You can nest logical operators as deeply as needed:
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
{
|
|
216
|
+
"filter": {
|
|
217
|
+
"0": ["AND",
|
|
218
|
+
{"status": {"IN": [1, 2]}},
|
|
219
|
+
{"visibility": 0},
|
|
220
|
+
{"1": ["OR",
|
|
221
|
+
{"priority": {">=": 3}},
|
|
222
|
+
{"duedate": {"<": "2025-06-01"}}
|
|
223
|
+
]}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Search Queries
|
|
230
|
+
|
|
231
|
+
The `query` parameter performs a search across all searchable string fields for a resource (typically `name`, `description`, and similar columns):
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"query": "server outage"
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
You can combine `query` with `filter` to narrow results further:
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"query": "payment",
|
|
244
|
+
"filter": {"status": 1}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**JavaScript client:**
|
|
249
|
+
|
|
250
|
+
```js
|
|
251
|
+
const results = await client.api.listTickets({
|
|
252
|
+
query: 'server outage',
|
|
253
|
+
filters: { status: 1 },
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Sorting
|
|
258
|
+
|
|
259
|
+
Control the order of results using the `sort` parameter. Provide an array of field names, each prefixed with `+` for ascending or `-` for descending:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"sort": ["+lastname", "-contact.country"]
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
| Prefix | Direction | Example |
|
|
268
|
+
|--------|-----------|---------|
|
|
269
|
+
| `+` | Ascending (A-Z, 0-9, oldest first) | `"+lastname"` |
|
|
270
|
+
| `-` | Descending (Z-A, 9-0, newest first) | `"-lastmodified"` |
|
|
271
|
+
|
|
272
|
+
Multiple sort fields are applied in order -- the example above sorts by `lastname` ascending first, then by `contact.country` descending within each name.
|
|
273
|
+
|
|
274
|
+
:::tip
|
|
275
|
+
Sort by `"-lastmodified"` to get the most recently updated records first. This is a common default for dashboard-style views.
|
|
276
|
+
:::
|
|
277
|
+
|
|
278
|
+
## Distinct Results
|
|
279
|
+
|
|
280
|
+
The `distinct` parameter eliminates duplicate rows from the result set. This is useful when a query returns multiple rows for the same record due to joins or multi-value fields.
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"distinct": true,
|
|
285
|
+
"fields": ["ID", "lastname", "contact.country"],
|
|
286
|
+
"filter": { "visibility": 0 }
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**JavaScript client:**
|
|
291
|
+
|
|
292
|
+
```js
|
|
293
|
+
const result = await client.api.listAccounts({
|
|
294
|
+
distinct: true,
|
|
295
|
+
fields: ['ID', 'lastname', 'contact.country'],
|
|
296
|
+
filters: { visibility: 0 },
|
|
297
|
+
});
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Pagination
|
|
301
|
+
|
|
302
|
+
The API supports offset-based pagination using `limit` and `offset`:
|
|
303
|
+
|
|
304
|
+
| Parameter | Type | Default | Max | Description |
|
|
305
|
+
|-----------|------|---------|-----|-------------|
|
|
306
|
+
| `limit` | integer | `1000` | `10000` | Maximum number of records to return |
|
|
307
|
+
| `offset` | integer | `0` | — | Number of records to skip before returning results |
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"limit": 25,
|
|
312
|
+
"offset": 50
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
:::info Default limit
|
|
317
|
+
When no `limit` is specified, the API returns up to **1000** records. The maximum supported value is **10000**. For large datasets, always paginate using `limit` and `offset`.
|
|
318
|
+
:::
|
|
319
|
+
|
|
320
|
+
### Getting the Total Count
|
|
321
|
+
|
|
322
|
+
To retrieve the total number of matching records without fetching the data itself, set `count` to `1`. The response will contain only the count:
|
|
323
|
+
|
|
324
|
+
**Request:**
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"count": true,
|
|
329
|
+
"filter": {
|
|
330
|
+
"visibility": 0,
|
|
331
|
+
"contact.country": {"IN": ["DE", "AT", "GB"]},
|
|
332
|
+
"2": ["OR",
|
|
333
|
+
{"lastmodified": {">": 1524472045}},
|
|
334
|
+
{"contact.lastmodified": {">": 1524472045}}
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Response:**
|
|
341
|
+
|
|
342
|
+
```json
|
|
343
|
+
{
|
|
344
|
+
"count": 5
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**JavaScript client:**
|
|
349
|
+
|
|
350
|
+
```js
|
|
351
|
+
const countResult = await client.api.listAccounts({
|
|
352
|
+
count: true,
|
|
353
|
+
filters: { visibility: 0 },
|
|
354
|
+
});
|
|
355
|
+
// countResult => { count: 5 }
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
:::info
|
|
359
|
+
Use `count` to build pagination controls in your UI. First request the count to determine the total number of pages, then paginate through results using `limit` and `offset`. Higher-level client helpers may normalize count-enabled responses differently, so keep the raw API shape and the client-layer shape conceptually separate.
|
|
360
|
+
:::
|
|
361
|
+
|
|
362
|
+
## Expanding JSON and Binary Data
|
|
363
|
+
|
|
364
|
+
Some table columns contain JSON data or reference binary files. By default, these columns are not expanded in list responses. The `expand` parameter tells the API to load and inline the column's content automatically.
|
|
365
|
+
|
|
366
|
+
:::warning
|
|
367
|
+
The `expand` parameter is **only** for JSON data columns (like `items` in transactions or `data` in objects) and binary file references (like `binfile`). It is **not** used for extended data fields -- see [Extended Data (extdata)](#extended-data-extdata) below.
|
|
368
|
+
:::
|
|
369
|
+
|
|
370
|
+
**Example -- expanding a binary file column:**
|
|
371
|
+
|
|
372
|
+
```json
|
|
373
|
+
{
|
|
374
|
+
"fields": ["ID", "subject", "binfile"],
|
|
375
|
+
"expand": ["binfile"],
|
|
376
|
+
"limit": 1
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**curl:**
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
curl -X POST "https://cloud.zeyos.com/demo/api/v1/messages/" \
|
|
384
|
+
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
|
|
385
|
+
-H "Content-Type: application/json" \
|
|
386
|
+
-d '{
|
|
387
|
+
"fields": ["ID", "subject", "binfile"],
|
|
388
|
+
"expand": ["binfile"],
|
|
389
|
+
"limit": 1
|
|
390
|
+
}'
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Response:**
|
|
394
|
+
|
|
395
|
+
```json
|
|
396
|
+
[{"ID": 188, "subject": "Test", "binfile": {"content": "UmV0dXJuLVBhdGg6IDx..."}}]
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The binary content is returned inline as base64-encoded data. In the example above, the `binfile` column is expanded to include the full email message content as [RFC 822](https://www.ietf.org/rfc/rfc822.txt).
|
|
400
|
+
|
|
401
|
+
Other common use cases for `expand`:
|
|
402
|
+
- `items` in transaction records (invoice line items as JSON)
|
|
403
|
+
- `data` in object records (structured JSON data)
|
|
404
|
+
|
|
405
|
+
## Extended Data (extdata)
|
|
406
|
+
|
|
407
|
+
Extended data (`extdata`) is a concept in ZeyOS that allows storing additional custom values for any entity. Whenever you create a new form field in ZeyOS, the field's value is stored in `extdata`. Accessing extdata is **separate** from the `expand` parameter.
|
|
408
|
+
|
|
409
|
+
### In List Requests (POST)
|
|
410
|
+
|
|
411
|
+
There are two ways to include extended data in list responses:
|
|
412
|
+
|
|
413
|
+
**Option 1: Select specific extdata fields via dot-notation in `fields`:**
|
|
414
|
+
|
|
415
|
+
```json
|
|
416
|
+
{
|
|
417
|
+
"fields": {
|
|
418
|
+
"Id": "ID",
|
|
419
|
+
"Name": "lastname",
|
|
420
|
+
"Nickname": "extdata.nickname",
|
|
421
|
+
"Department": "extdata.department"
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
This approach lets you pick individual extdata fields and give them aliases.
|
|
427
|
+
|
|
428
|
+
**Option 2: Include all extdata using the `extdata` body parameter:**
|
|
429
|
+
|
|
430
|
+
```json
|
|
431
|
+
{
|
|
432
|
+
"fields": ["ID", "lastname", "status"],
|
|
433
|
+
"extdata": 1,
|
|
434
|
+
"limit": 10
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
**JavaScript client:**
|
|
439
|
+
|
|
440
|
+
```js
|
|
441
|
+
// Select specific extdata fields
|
|
442
|
+
const result = await client.api.listAccounts({
|
|
443
|
+
fields: {
|
|
444
|
+
Id: 'ID',
|
|
445
|
+
Name: 'lastname',
|
|
446
|
+
Nickname: 'extdata.nickname',
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
// Or include all extdata
|
|
451
|
+
const result = await client.api.listAccounts({
|
|
452
|
+
fields: ['ID', 'lastname', 'status'],
|
|
453
|
+
extdata: 1,
|
|
454
|
+
limit: 10,
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### In GET Requests
|
|
459
|
+
|
|
460
|
+
When fetching a single record, pass `extdata=1` as a query parameter:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
curl "https://cloud.zeyos.com/demo/api/v1/accounts/42?extdata=1" \
|
|
464
|
+
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**JavaScript client:**
|
|
468
|
+
|
|
469
|
+
```js
|
|
470
|
+
const account = await client.api.getAccount({
|
|
471
|
+
ID: 42,
|
|
472
|
+
extdata: 1,
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## Complete Example
|
|
477
|
+
|
|
478
|
+
Here is the canonical example from the ZeyOS documentation, combining field selection with aliases, dot-notation joins, extdata fields, composite filters, sorting, and pagination.
|
|
479
|
+
|
|
480
|
+
### Query
|
|
481
|
+
|
|
482
|
+
```json
|
|
483
|
+
{
|
|
484
|
+
"fields": {
|
|
485
|
+
"Id": "ID",
|
|
486
|
+
"Name": "lastname",
|
|
487
|
+
"Nickname": "extdata.nickname",
|
|
488
|
+
"Address": "contact.address",
|
|
489
|
+
"Postalcode": "contact.postalcode",
|
|
490
|
+
"Town": "contact.city",
|
|
491
|
+
"SalesAgent": "assigneduser.name"
|
|
492
|
+
},
|
|
493
|
+
"filter": {
|
|
494
|
+
"visibility": 0,
|
|
495
|
+
"contact.country": {"IN": ["DE", "AT", "GB"]},
|
|
496
|
+
"2": ["OR",
|
|
497
|
+
{"lastmodified": {">": 1524472045}},
|
|
498
|
+
{"contact.lastmodified": {">": 1524472045}}
|
|
499
|
+
]
|
|
500
|
+
},
|
|
501
|
+
"sort": ["+lastname", "-contact.country"],
|
|
502
|
+
"limit": 3,
|
|
503
|
+
"offset": 0
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Using curl
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
curl -X POST "https://cloud.zeyos.com/demo/api/v1/accounts/" \
|
|
511
|
+
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
|
|
512
|
+
-H "Content-Type: application/json" \
|
|
513
|
+
-d '{
|
|
514
|
+
"fields": {
|
|
515
|
+
"Id": "ID",
|
|
516
|
+
"Name": "lastname",
|
|
517
|
+
"Nickname": "extdata.nickname",
|
|
518
|
+
"Address": "contact.address",
|
|
519
|
+
"Postalcode": "contact.postalcode",
|
|
520
|
+
"Town": "contact.city",
|
|
521
|
+
"SalesAgent": "assigneduser.name"
|
|
522
|
+
},
|
|
523
|
+
"filter": {
|
|
524
|
+
"visibility": 0,
|
|
525
|
+
"contact.country": {"IN": ["DE", "AT", "GB"]},
|
|
526
|
+
"2": ["OR",
|
|
527
|
+
{"lastmodified": {">": 1524472045}},
|
|
528
|
+
{"contact.lastmodified": {">": 1524472045}}
|
|
529
|
+
]
|
|
530
|
+
},
|
|
531
|
+
"sort": ["+lastname", "-contact.country"],
|
|
532
|
+
"limit": 3,
|
|
533
|
+
"offset": 0
|
|
534
|
+
}'
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Using the JavaScript Client
|
|
538
|
+
|
|
539
|
+
```js
|
|
540
|
+
const accounts = await client.api.listAccounts({
|
|
541
|
+
fields: {
|
|
542
|
+
Id: 'ID',
|
|
543
|
+
Name: 'lastname',
|
|
544
|
+
Nickname: 'extdata.nickname',
|
|
545
|
+
Address: 'contact.address',
|
|
546
|
+
Postalcode: 'contact.postalcode',
|
|
547
|
+
Town: 'contact.city',
|
|
548
|
+
SalesAgent: 'assigneduser.name',
|
|
549
|
+
},
|
|
550
|
+
filters: {
|
|
551
|
+
visibility: 0,
|
|
552
|
+
'contact.country': { IN: ['DE', 'AT', 'GB'] },
|
|
553
|
+
2: [
|
|
554
|
+
'OR',
|
|
555
|
+
{ lastmodified: { '>': 1524472045 } },
|
|
556
|
+
{ 'contact.lastmodified': { '>': 1524472045 } },
|
|
557
|
+
],
|
|
558
|
+
},
|
|
559
|
+
sort: ['+lastname', '-contact.country'],
|
|
560
|
+
limit: 3,
|
|
561
|
+
offset: 0,
|
|
562
|
+
});
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Response
|
|
566
|
+
|
|
567
|
+
```json
|
|
568
|
+
[
|
|
569
|
+
{
|
|
570
|
+
"Id": 2,
|
|
571
|
+
"Name": "BEQ Building Equipment",
|
|
572
|
+
"Nickname": null,
|
|
573
|
+
"Address": "Queensstreet",
|
|
574
|
+
"Postalcode": "12923",
|
|
575
|
+
"Town": "London",
|
|
576
|
+
"SalesAgent": "Max Mueller"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"Id": 15,
|
|
580
|
+
"Name": "CleanTexx",
|
|
581
|
+
"Nickname": null,
|
|
582
|
+
"Address": "Tower Bridge",
|
|
583
|
+
"Postalcode": "12923",
|
|
584
|
+
"Town": "London",
|
|
585
|
+
"SalesAgent": null
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
"Id": 1,
|
|
589
|
+
"Name": "Lightexx AG",
|
|
590
|
+
"Nickname": null,
|
|
591
|
+
"Address": "Schmittstr. 4",
|
|
592
|
+
"Postalcode": "80172",
|
|
593
|
+
"Town": "Munich",
|
|
594
|
+
"SalesAgent": null
|
|
595
|
+
}
|
|
596
|
+
]
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
:::tip
|
|
600
|
+
When building interactive UIs, start with a `count` request to determine the total result set size, then use `limit` and `offset` to implement paginated loading.
|
|
601
|
+
:::
|