@fourier-labs/harbour-contracts 0.72.0 → 0.74.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.
Files changed (31) hide show
  1. package/README.md +2 -2
  2. package/contract-release.json +24 -24
  3. package/dist/gen-ts/app-integrations-declaration.d.ts +29 -20
  4. package/dist/gen-ts/contract-release.d.ts +6 -6
  5. package/dist/gen-ts/contract-release.js +6 -6
  6. package/dist/gen-ts/data-grant-v2.d.ts +2 -2
  7. package/dist/gen-ts/data-source.d.ts +19 -2
  8. package/dist/gen-ts/integration-error-details.d.ts +2 -2
  9. package/dist/gen-ts/integration-execute-input-rules.d.ts +35 -0
  10. package/dist/gen-ts/integration-execute-input-rules.js +15 -0
  11. package/dist/gen-ts/integration-execute-request.d.ts +24 -2
  12. package/dist/gen-ts/integration-execute-result.d.ts +9 -0
  13. package/dist/gen-ts/integration-operations.d.ts +7 -0
  14. package/dist/gen-ts/integration-operations.js +9 -0
  15. package/dist/gen-ts/saas-connection.d.ts +1 -1
  16. package/gen-ts/app-integrations-declaration.ts +29 -20
  17. package/gen-ts/contract-release.ts +6 -6
  18. package/gen-ts/data-grant-v2.ts +2 -1
  19. package/gen-ts/data-source.ts +19 -2
  20. package/gen-ts/integration-error-details.ts +3 -2
  21. package/gen-ts/integration-execute-input-rules.ts +15 -0
  22. package/gen-ts/integration-execute-request.ts +25 -2
  23. package/gen-ts/integration-execute-result.ts +9 -0
  24. package/gen-ts/integration-operations.ts +9 -0
  25. package/gen-ts/saas-connection.ts +1 -0
  26. package/package.json +1 -1
  27. package/schema/app-integrations-declaration.schema.json +478 -67
  28. package/schema/data-source.schema.json +57 -2
  29. package/schema/integration-error-details.schema.json +3 -2
  30. package/schema/integration-execute-request.schema.json +905 -120
  31. package/schema/integration-execute-result.schema.json +520 -82
@@ -2,160 +2,598 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "https://schemas.harbour.dev/integration-execute-result.schema.json",
4
4
  "title": "IntegrationExecuteResult",
5
- "description": "The `data` member of a successful execute response `{data, requestId}`; the SDK unwraps `data`. Exactly one of the operation results (twelve operations since 0.71.0, ADR 0018): slack.channel.history -> {messages, hasMore, nextCursor?} (plain text/IDs/time, plus the display name and emoji icon a per-app-named app post carries — authorName/authorIcon, 0.55.0 — never the provider payload; `nextCursor` when hasMore, to pass as the next read's `cursor`); slack.message.post, slack.message.update, slack.message.delete -> {messageId} (the Slack ts); slack.dm.send -> {messageId, channelId} (the ts and the DM channel it went to); slack.user.lookup -> {userId, displayName}; gmail.thread.list -> {threads, hasMore, nextPageToken?} (newest matching threads; each `messageId` is the thread's newest message, what gmail.message.read takes; `nextPageToken` when hasMore); gmail.thread.read -> {id, emails} (every message of the thread, oldest first, each shaped like a gmail.message.read result); gmail.message.read -> {id, threadId, subject, from, to, date, text, truncated, attachments?} (headers plus the plain text with html stripped, cut at 16 KiB with `truncated` set; `attachments` lists the files without their bytes, which gmail.attachment.read fetches by id); gmail.attachment.read -> {filename, mimeType, size, dataBase64}; gmail.message.send -> {messageId, threadId} (the Gmail ids of the sent message and its thread); warehouse.view.read -> {rows, truncated} (rows keyed by the selected columns, or for an aggregate read by the groupBy columns then the aggregate aliases; decimal/64-bit values as strings, dates as ISO strings; since 0.70.0 every server sends `truncated`, true when more rows matched than `limit` — the server reads limit+1 rows to know — so the rows are incomplete and must not be totalled or averaged; a server before 0.70.0 omitted it). An unknown send outcome is never a result; it is an error with details.code SEND_OUTCOME_UNKNOWN. A whole result over 1 MiB is rejected, never cut down to fit — except a gmail.attachment.read, whose single attachment is bounded by its own 2 MiB.",
5
+ "description": "The `data` member of a successful execute response `{data, requestId}`; the SDK unwraps `data`. Exactly one of the operation results (twelve operations since 0.71.0, ADR 0018): slack.channel.history -> {messages, hasMore, nextCursor?} (plain text/IDs/time, plus the display name and emoji icon a per-app-named app post carries \u2014 authorName/authorIcon, 0.55.0 \u2014 never the provider payload; `nextCursor` when hasMore, to pass as the next read's `cursor`); slack.message.post, slack.message.update, slack.message.delete -> {messageId} (the Slack ts); slack.dm.send -> {messageId, channelId} (the ts and the DM channel it went to); slack.user.lookup -> {userId, displayName}; gmail.thread.list -> {threads, hasMore, nextPageToken?} (newest matching threads; each `messageId` is the thread's newest message, what gmail.message.read takes; `nextPageToken` when hasMore); gmail.thread.read -> {id, emails} (every message of the thread, oldest first, each shaped like a gmail.message.read result); gmail.message.read -> {id, threadId, subject, from, to, date, text, truncated, attachments?} (headers plus the plain text with html stripped, cut at 16 KiB with `truncated` set; `attachments` lists the files without their bytes, which gmail.attachment.read fetches by id); gmail.attachment.read -> {filename, mimeType, size, dataBase64}; gmail.message.send -> {messageId, threadId} (the Gmail ids of the sent message and its thread); warehouse.view.read -> {rows, truncated} (rows keyed by the selected columns, or for an aggregate read by the groupBy columns then the aggregate aliases; decimal/64-bit values as strings, dates as ISO strings; since 0.70.0 every server sends `truncated`, true when more rows matched than `limit` \u2014 the server reads limit+1 rows to know \u2014 so the rows are incomplete and must not be totalled or averaged; a server before 0.70.0 omitted it). An unknown send outcome is never a result; it is an error with details.code SEND_OUTCOME_UNKNOWN. A whole result over 1 MiB is rejected, never cut down to fit \u2014 except a gmail.attachment.read, whose single attachment is bounded by its own 2 MiB.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "properties": {
9
9
  "messages": {
10
10
  "type": "array",
11
11
  "maxItems": 100,
12
- "items": { "$ref": "#/definitions/ChannelMessage" }
13
- },
14
- "hasMore": { "type": "boolean" },
15
- "nextCursor": { "type": "string", "minLength": 1, "maxLength": 256, "description": "slack.channel.history (0.71.0): the cursor of the next (older) page, present only when hasMore." },
16
- "messageId": { "type": "string", "minLength": 1, "maxLength": 128 },
17
- "channelId": { "type": "string", "pattern": "^[A-Z0-9]{5,20}$", "description": "slack.dm.send (0.71.0): the Slack DM channel id the message went to." },
18
- "userId": { "type": "string", "minLength": 1, "maxLength": 128, "description": "slack.user.lookup (0.71.0): the Slack user id of the member with that email." },
19
- "displayName": { "type": "string", "maxLength": 256, "description": "slack.user.lookup (0.71.0): the member's display name, or real name when they set no display name; may be empty." },
12
+ "items": {
13
+ "$ref": "#/definitions/ChannelMessage"
14
+ }
15
+ },
16
+ "hasMore": {
17
+ "type": "boolean"
18
+ },
19
+ "nextCursor": {
20
+ "type": "string",
21
+ "minLength": 1,
22
+ "maxLength": 256,
23
+ "description": "slack.channel.history (0.71.0): the cursor of the next (older) page, present only when hasMore."
24
+ },
25
+ "messageId": {
26
+ "type": "string",
27
+ "minLength": 1,
28
+ "maxLength": 128
29
+ },
30
+ "channelId": {
31
+ "type": "string",
32
+ "pattern": "^[A-Z0-9]{5,20}$",
33
+ "description": "slack.dm.send (0.71.0): the Slack DM channel id the message went to."
34
+ },
35
+ "userId": {
36
+ "type": "string",
37
+ "minLength": 1,
38
+ "maxLength": 128,
39
+ "description": "slack.user.lookup (0.71.0): the Slack user id of the member with that email."
40
+ },
41
+ "displayName": {
42
+ "type": "string",
43
+ "maxLength": 256,
44
+ "description": "slack.user.lookup (0.71.0): the member's display name, or real name when they set no display name; may be empty."
45
+ },
20
46
  "threads": {
21
47
  "type": "array",
22
48
  "maxItems": 50,
23
- "items": { "$ref": "#/definitions/GmailThread" }
24
- },
25
- "nextPageToken": { "type": "string", "minLength": 1, "maxLength": 256, "description": "gmail.thread.list (0.71.0): the token of the next page, present only when hasMore." },
26
- "id": { "type": "string", "minLength": 1, "maxLength": 128 },
27
- "threadId": { "type": "string", "minLength": 1, "maxLength": 128 },
28
- "subject": { "type": "string", "maxLength": 2048 },
29
- "from": { "type": "string", "maxLength": 2048 },
30
- "to": { "type": "string", "maxLength": 8192 },
31
- "date": { "type": "string", "maxLength": 128 },
32
- "text": { "type": "string", "maxLength": 16384 },
33
- "truncated": { "type": "boolean", "description": "gmail.message.read: the text was cut at 16 KiB. warehouse.view.read (0.70.0): more rows matched than the read's limit, so `rows` is incomplete." },
49
+ "items": {
50
+ "$ref": "#/definitions/GmailThread"
51
+ }
52
+ },
53
+ "nextPageToken": {
54
+ "type": "string",
55
+ "minLength": 1,
56
+ "maxLength": 256,
57
+ "description": "gmail.thread.list (0.71.0): the token of the next page, present only when hasMore."
58
+ },
59
+ "id": {
60
+ "type": "string",
61
+ "minLength": 1,
62
+ "maxLength": 128
63
+ },
64
+ "threadId": {
65
+ "type": "string",
66
+ "minLength": 1,
67
+ "maxLength": 128
68
+ },
69
+ "subject": {
70
+ "type": "string",
71
+ "maxLength": 2048
72
+ },
73
+ "from": {
74
+ "type": "string",
75
+ "maxLength": 2048
76
+ },
77
+ "to": {
78
+ "type": "string",
79
+ "maxLength": 8192
80
+ },
81
+ "date": {
82
+ "type": "string",
83
+ "maxLength": 128
84
+ },
85
+ "text": {
86
+ "type": "string",
87
+ "maxLength": 16384
88
+ },
89
+ "truncated": {
90
+ "type": "boolean",
91
+ "description": "gmail.message.read: the text was cut at 16 KiB. warehouse.view.read (0.70.0): more rows matched than the read's limit, so `rows` is incomplete."
92
+ },
93
+ "sample": {
94
+ "type": "boolean",
95
+ "description": "warehouse.view.read (0.74.0): true when `rows` came from the app's sample rows (integration-execute-request.sampleRows) because the development read had no development copy of the source; the rows were never read from the source. Absent or false: the rows came from the source."
96
+ },
34
97
  "attachments": {
35
98
  "type": "array",
36
99
  "maxItems": 100,
37
- "items": { "$ref": "#/definitions/GmailAttachment" },
100
+ "items": {
101
+ "$ref": "#/definitions/GmailAttachment"
102
+ },
38
103
  "description": "gmail.message.read (0.71.0): the message's attachments, without their bytes."
39
104
  },
40
105
  "emails": {
41
106
  "type": "array",
42
107
  "maxItems": 100,
43
- "items": { "$ref": "#/definitions/GmailMessage" },
108
+ "items": {
109
+ "$ref": "#/definitions/GmailMessage"
110
+ },
44
111
  "description": "gmail.thread.read (0.71.0): every message of the thread, oldest first."
45
112
  },
46
- "filename": { "type": "string", "minLength": 1, "maxLength": 255 },
47
- "mimeType": { "type": "string", "minLength": 1, "maxLength": 128 },
48
- "size": { "type": "integer", "minimum": 0, "description": "gmail.attachment.read (0.71.0): the attachment's size in bytes." },
49
- "dataBase64": { "type": "string", "maxLength": 2796203, "description": "gmail.attachment.read (0.71.0): the attachment's bytes, standard base64, at most 2 MiB of bytes." },
113
+ "filename": {
114
+ "type": "string",
115
+ "minLength": 1,
116
+ "maxLength": 255
117
+ },
118
+ "mimeType": {
119
+ "type": "string",
120
+ "minLength": 1,
121
+ "maxLength": 128
122
+ },
123
+ "size": {
124
+ "type": "integer",
125
+ "minimum": 0,
126
+ "description": "gmail.attachment.read (0.71.0): the attachment's size in bytes."
127
+ },
128
+ "dataBase64": {
129
+ "type": "string",
130
+ "maxLength": 2796203,
131
+ "description": "gmail.attachment.read (0.71.0): the attachment's bytes, standard base64, at most 2 MiB of bytes."
132
+ },
50
133
  "rows": {
51
134
  "type": "array",
52
135
  "maxItems": 1000,
53
- "items": { "type": "object", "additionalProperties": {}, "description": "One row keyed by the selected column names, or by the groupBy columns then the aggregate aliases." }
54
- }
136
+ "items": {
137
+ "type": "object",
138
+ "additionalProperties": {},
139
+ "description": "One row keyed by the selected column names, or by the groupBy columns then the aggregate aliases."
140
+ }
141
+ },
142
+ "status": {
143
+ "type": "integer"
144
+ },
145
+ "headers": {
146
+ "type": "object",
147
+ "additionalProperties": {
148
+ "type": "string"
149
+ }
150
+ },
151
+ "body": {}
55
152
  },
56
153
  "oneOf": [
57
- { "required": ["messages", "hasMore"], "propertyNames": { "enum": ["messages", "hasMore", "nextCursor"] } },
58
- { "required": ["messageId"], "maxProperties": 1 },
59
- { "required": ["messageId", "threadId"], "maxProperties": 2 },
60
- { "required": ["messageId", "channelId"], "maxProperties": 2 },
61
- { "required": ["userId", "displayName"], "maxProperties": 2 },
62
- { "required": ["threads", "hasMore"], "propertyNames": { "enum": ["threads", "hasMore", "nextPageToken"] } },
63
- { "required": ["id", "emails"], "maxProperties": 2 },
64
- { "required": ["id", "threadId", "subject", "from", "to", "date", "text", "truncated"], "propertyNames": { "enum": ["id", "threadId", "subject", "from", "to", "date", "text", "truncated", "attachments"] } },
65
- { "required": ["filename", "mimeType", "size", "dataBase64"], "maxProperties": 4 },
66
- { "required": ["rows"], "propertyNames": { "enum": ["rows", "truncated"] } }
154
+ {
155
+ "required": [
156
+ "messages",
157
+ "hasMore"
158
+ ],
159
+ "propertyNames": {
160
+ "enum": [
161
+ "messages",
162
+ "hasMore",
163
+ "nextCursor"
164
+ ]
165
+ }
166
+ },
167
+ {
168
+ "required": [
169
+ "messageId"
170
+ ],
171
+ "maxProperties": 1
172
+ },
173
+ {
174
+ "required": [
175
+ "messageId",
176
+ "threadId"
177
+ ],
178
+ "maxProperties": 2
179
+ },
180
+ {
181
+ "required": [
182
+ "messageId",
183
+ "channelId"
184
+ ],
185
+ "maxProperties": 2
186
+ },
187
+ {
188
+ "required": [
189
+ "userId",
190
+ "displayName"
191
+ ],
192
+ "maxProperties": 2
193
+ },
194
+ {
195
+ "required": [
196
+ "threads",
197
+ "hasMore"
198
+ ],
199
+ "propertyNames": {
200
+ "enum": [
201
+ "threads",
202
+ "hasMore",
203
+ "nextPageToken"
204
+ ]
205
+ }
206
+ },
207
+ {
208
+ "required": [
209
+ "id",
210
+ "emails"
211
+ ],
212
+ "maxProperties": 2
213
+ },
214
+ {
215
+ "required": [
216
+ "id",
217
+ "threadId",
218
+ "subject",
219
+ "from",
220
+ "to",
221
+ "date",
222
+ "text",
223
+ "truncated"
224
+ ],
225
+ "propertyNames": {
226
+ "enum": [
227
+ "id",
228
+ "threadId",
229
+ "subject",
230
+ "from",
231
+ "to",
232
+ "date",
233
+ "text",
234
+ "truncated",
235
+ "attachments"
236
+ ]
237
+ }
238
+ },
239
+ {
240
+ "required": [
241
+ "filename",
242
+ "mimeType",
243
+ "size",
244
+ "dataBase64"
245
+ ],
246
+ "maxProperties": 4
247
+ },
248
+ {
249
+ "required": [
250
+ "rows"
251
+ ],
252
+ "propertyNames": {
253
+ "enum": [
254
+ "rows",
255
+ "truncated",
256
+ "sample"
257
+ ]
258
+ }
259
+ }
67
260
  ],
68
261
  "definitions": {
69
262
  "GmailAttachment": {
70
263
  "type": "object",
71
264
  "additionalProperties": false,
72
- "required": ["id", "filename", "mimeType", "size"],
265
+ "required": [
266
+ "id",
267
+ "filename",
268
+ "mimeType",
269
+ "size"
270
+ ],
73
271
  "description": "One attachment of a Gmail message (0.71.0), named without its bytes; gmail.attachment.read fetches them by `id`.",
74
272
  "properties": {
75
- "id": { "type": "string", "minLength": 1, "maxLength": 512 },
76
- "filename": { "type": "string", "maxLength": 255 },
77
- "mimeType": { "type": "string", "maxLength": 128 },
78
- "size": { "type": "integer", "minimum": 0, "description": "Bytes." }
273
+ "id": {
274
+ "type": "string",
275
+ "minLength": 1,
276
+ "maxLength": 512
277
+ },
278
+ "filename": {
279
+ "type": "string",
280
+ "maxLength": 255
281
+ },
282
+ "mimeType": {
283
+ "type": "string",
284
+ "maxLength": 128
285
+ },
286
+ "size": {
287
+ "type": "integer",
288
+ "minimum": 0,
289
+ "description": "Bytes."
290
+ }
79
291
  }
80
292
  },
81
293
  "GmailMessage": {
82
294
  "type": "object",
83
295
  "additionalProperties": false,
84
- "required": ["id", "threadId", "subject", "from", "to", "date", "text", "truncated"],
296
+ "required": [
297
+ "id",
298
+ "threadId",
299
+ "subject",
300
+ "from",
301
+ "to",
302
+ "date",
303
+ "text",
304
+ "truncated"
305
+ ],
85
306
  "description": "One message of a gmail.thread.read result (0.71.0): the gmail.message.read shape.",
86
307
  "properties": {
87
- "id": { "type": "string", "minLength": 1, "maxLength": 128 },
88
- "threadId": { "type": "string", "minLength": 1, "maxLength": 128 },
89
- "subject": { "type": "string", "maxLength": 2048 },
90
- "from": { "type": "string", "maxLength": 2048 },
91
- "to": { "type": "string", "maxLength": 8192 },
92
- "date": { "type": "string", "maxLength": 128 },
93
- "text": { "type": "string", "maxLength": 16384 },
94
- "truncated": { "type": "boolean" },
95
- "attachments": { "type": "array", "maxItems": 100, "items": { "$ref": "#/definitions/GmailAttachment" } }
308
+ "id": {
309
+ "type": "string",
310
+ "minLength": 1,
311
+ "maxLength": 128
312
+ },
313
+ "threadId": {
314
+ "type": "string",
315
+ "minLength": 1,
316
+ "maxLength": 128
317
+ },
318
+ "subject": {
319
+ "type": "string",
320
+ "maxLength": 2048
321
+ },
322
+ "from": {
323
+ "type": "string",
324
+ "maxLength": 2048
325
+ },
326
+ "to": {
327
+ "type": "string",
328
+ "maxLength": 8192
329
+ },
330
+ "date": {
331
+ "type": "string",
332
+ "maxLength": 128
333
+ },
334
+ "text": {
335
+ "type": "string",
336
+ "maxLength": 16384
337
+ },
338
+ "truncated": {
339
+ "type": "boolean"
340
+ },
341
+ "attachments": {
342
+ "type": "array",
343
+ "maxItems": 100,
344
+ "items": {
345
+ "$ref": "#/definitions/GmailAttachment"
346
+ }
347
+ }
96
348
  }
97
349
  },
98
350
  "GmailThread": {
99
351
  "type": "object",
100
352
  "additionalProperties": false,
101
- "required": ["id", "messageId", "subject", "from", "date", "snippet"],
353
+ "required": [
354
+ "id",
355
+ "messageId",
356
+ "subject",
357
+ "from",
358
+ "date",
359
+ "snippet"
360
+ ],
102
361
  "properties": {
103
- "id": { "type": "string", "minLength": 1, "maxLength": 128 },
104
- "messageId": { "type": "string", "minLength": 1, "maxLength": 128 },
105
- "subject": { "type": "string", "maxLength": 2048 },
106
- "from": { "type": "string", "maxLength": 2048 },
107
- "date": { "type": "string", "maxLength": 128 },
108
- "snippet": { "type": "string", "maxLength": 4096 }
362
+ "id": {
363
+ "type": "string",
364
+ "minLength": 1,
365
+ "maxLength": 128
366
+ },
367
+ "messageId": {
368
+ "type": "string",
369
+ "minLength": 1,
370
+ "maxLength": 128
371
+ },
372
+ "subject": {
373
+ "type": "string",
374
+ "maxLength": 2048
375
+ },
376
+ "from": {
377
+ "type": "string",
378
+ "maxLength": 2048
379
+ },
380
+ "date": {
381
+ "type": "string",
382
+ "maxLength": 128
383
+ },
384
+ "snippet": {
385
+ "type": "string",
386
+ "maxLength": 4096
387
+ }
109
388
  }
110
389
  },
111
390
  "ChannelMessage": {
112
391
  "type": "object",
113
392
  "additionalProperties": false,
114
- "required": ["id", "text", "authorId", "createdAt"],
393
+ "required": [
394
+ "id",
395
+ "text",
396
+ "authorId",
397
+ "createdAt"
398
+ ],
115
399
  "properties": {
116
- "id": { "type": "string", "minLength": 1, "maxLength": 128 },
117
- "text": { "type": "string", "maxLength": 40000 },
118
- "authorId": { "type": "string", "minLength": 1, "maxLength": 128 },
119
- "createdAt": { "type": "string", "format": "date-time" },
120
- "authorName": { "type": "string", "minLength": 1, "maxLength": 128, "description": "The display name a per-app-named app post carries (0.55.0; Slack's `username` on a customised bot message), so an app can recognise its own posts in a channel; absent on a person's message and on a post under the bot's own name." },
121
- "authorIcon": { "type": "string", "pattern": "^:[a-z0-9_+-]{1,60}:$", "description": "The emoji shortcode such a post carries as its icon (0.55.0), when it has one; never an image URL." }
400
+ "id": {
401
+ "type": "string",
402
+ "minLength": 1,
403
+ "maxLength": 128
404
+ },
405
+ "text": {
406
+ "type": "string",
407
+ "maxLength": 40000
408
+ },
409
+ "authorId": {
410
+ "type": "string",
411
+ "minLength": 1,
412
+ "maxLength": 128
413
+ },
414
+ "createdAt": {
415
+ "type": "string",
416
+ "format": "date-time"
417
+ },
418
+ "authorName": {
419
+ "type": "string",
420
+ "minLength": 1,
421
+ "maxLength": 128,
422
+ "description": "The display name a per-app-named app post carries (0.55.0; Slack's `username` on a customised bot message), so an app can recognise its own posts in a channel; absent on a person's message and on a post under the bot's own name."
423
+ },
424
+ "authorIcon": {
425
+ "type": "string",
426
+ "pattern": "^:[a-z0-9_+-]{1,60}:$",
427
+ "description": "The emoji shortcode such a post carries as its icon (0.55.0), when it has one; never an image URL."
428
+ }
122
429
  }
123
430
  }
124
431
  },
125
432
  "examples": [
126
433
  {
127
- "messages": [{ "id": "1725840000.000100", "text": "Shipped the weekly report.", "authorId": "U0123456", "createdAt": "2026-09-09T08:00:00Z" }],
434
+ "messages": [
435
+ {
436
+ "id": "1725840000.000100",
437
+ "text": "Shipped the weekly report.",
438
+ "authorId": "U0123456",
439
+ "createdAt": "2026-09-09T08:00:00Z"
440
+ }
441
+ ],
128
442
  "hasMore": false
129
443
  },
130
- { "messageId": "1725840100.000200" },
131
- { "messageId": "18f2c3a4b5d6e7f9", "threadId": "18f2c3a4b5d6e7f0" },
132
444
  {
133
- "threads": [{ "id": "18f2c3a4b5d6e7f0", "messageId": "18f2c3a4b5d6e7f8", "subject": "Weekly report", "from": "Jane <jane@example.com>", "date": "2026-09-11T08:00:00Z", "snippet": "Shipped the weekly report." }],
445
+ "messageId": "1725840100.000200"
446
+ },
447
+ {
448
+ "messageId": "18f2c3a4b5d6e7f9",
449
+ "threadId": "18f2c3a4b5d6e7f0"
450
+ },
451
+ {
452
+ "threads": [
453
+ {
454
+ "id": "18f2c3a4b5d6e7f0",
455
+ "messageId": "18f2c3a4b5d6e7f8",
456
+ "subject": "Weekly report",
457
+ "from": "Jane <jane@example.com>",
458
+ "date": "2026-09-11T08:00:00Z",
459
+ "snippet": "Shipped the weekly report."
460
+ }
461
+ ],
134
462
  "hasMore": false
135
463
  },
136
- { "id": "18f2c3a4b5d6e7f8", "threadId": "18f2c3a4b5d6e7f0", "subject": "Weekly report", "from": "Jane <jane@example.com>", "to": "team@example.com", "date": "2026-09-11T08:00:00Z", "text": "Shipped the weekly report.", "truncated": false },
137
- { "rows": [{ "week": "2026-W36", "total": "1234.50" }] },
138
- { "rows": [{ "region_code": "EMEA", "total_minor": "1234550", "invoices": "42" }, { "region_code": "APAC", "total_minor": "998000", "invoices": "17" }], "truncated": true },
139
464
  {
140
- "messages": [{ "id": "1725840000.000100", "text": "Shipped the weekly report.", "authorId": "U0123456", "createdAt": "2026-09-09T08:00:00Z" }],
465
+ "id": "18f2c3a4b5d6e7f8",
466
+ "threadId": "18f2c3a4b5d6e7f0",
467
+ "subject": "Weekly report",
468
+ "from": "Jane <jane@example.com>",
469
+ "to": "team@example.com",
470
+ "date": "2026-09-11T08:00:00Z",
471
+ "text": "Shipped the weekly report.",
472
+ "truncated": false
473
+ },
474
+ {
475
+ "rows": [
476
+ {
477
+ "week": "2026-W36",
478
+ "total": "1234.50"
479
+ }
480
+ ]
481
+ },
482
+ {
483
+ "rows": [
484
+ {
485
+ "region_code": "EMEA",
486
+ "total_minor": "1234550",
487
+ "invoices": "42"
488
+ },
489
+ {
490
+ "region_code": "APAC",
491
+ "total_minor": "998000",
492
+ "invoices": "17"
493
+ }
494
+ ],
495
+ "truncated": true
496
+ },
497
+ {
498
+ "messages": [
499
+ {
500
+ "id": "1725840000.000100",
501
+ "text": "Shipped the weekly report.",
502
+ "authorId": "U0123456",
503
+ "createdAt": "2026-09-09T08:00:00Z"
504
+ }
505
+ ],
141
506
  "hasMore": true,
142
507
  "nextCursor": "bmV4dF90czoxNzI1ODQwMDAwMDAwMTAw"
143
508
  },
144
- { "messageId": "1725840200.000300", "channelId": "D0123456DM" },
145
- { "userId": "U0123456", "displayName": "Jane Doe" },
146
509
  {
147
- "threads": [{ "id": "18f2c3a4b5d6e7f0", "messageId": "18f2c3a4b5d6e7f8", "subject": "Weekly report", "from": "Jane <jane@example.com>", "date": "2026-09-11T08:00:00Z", "snippet": "Shipped the weekly report." }],
510
+ "messageId": "1725840200.000300",
511
+ "channelId": "D0123456DM"
512
+ },
513
+ {
514
+ "userId": "U0123456",
515
+ "displayName": "Jane Doe"
516
+ },
517
+ {
518
+ "threads": [
519
+ {
520
+ "id": "18f2c3a4b5d6e7f0",
521
+ "messageId": "18f2c3a4b5d6e7f8",
522
+ "subject": "Weekly report",
523
+ "from": "Jane <jane@example.com>",
524
+ "date": "2026-09-11T08:00:00Z",
525
+ "snippet": "Shipped the weekly report."
526
+ }
527
+ ],
148
528
  "hasMore": true,
149
529
  "nextPageToken": "CAUQ0ZSH0b2DiwMg"
150
530
  },
151
531
  {
152
532
  "id": "18f2c3a4b5d6e7f0",
153
533
  "emails": [
154
- { "id": "18f2c3a4b5d6e7f7", "threadId": "18f2c3a4b5d6e7f0", "subject": "Weekly report", "from": "Jane <jane@example.com>", "to": "team@example.com", "date": "2026-09-10T08:00:00Z", "text": "Draft attached.", "truncated": false, "attachments": [{ "id": "ANGjdJ8w9h1Q2k3L4m5N6o7P8q9R0s", "filename": "weekly-report.pdf", "mimeType": "application/pdf", "size": 48213 }] },
155
- { "id": "18f2c3a4b5d6e7f8", "threadId": "18f2c3a4b5d6e7f0", "subject": "Re: Weekly report", "from": "Sam <sam@example.com>", "to": "team@example.com", "date": "2026-09-11T08:00:00Z", "text": "Shipped the weekly report.", "truncated": false }
534
+ {
535
+ "id": "18f2c3a4b5d6e7f7",
536
+ "threadId": "18f2c3a4b5d6e7f0",
537
+ "subject": "Weekly report",
538
+ "from": "Jane <jane@example.com>",
539
+ "to": "team@example.com",
540
+ "date": "2026-09-10T08:00:00Z",
541
+ "text": "Draft attached.",
542
+ "truncated": false,
543
+ "attachments": [
544
+ {
545
+ "id": "ANGjdJ8w9h1Q2k3L4m5N6o7P8q9R0s",
546
+ "filename": "weekly-report.pdf",
547
+ "mimeType": "application/pdf",
548
+ "size": 48213
549
+ }
550
+ ]
551
+ },
552
+ {
553
+ "id": "18f2c3a4b5d6e7f8",
554
+ "threadId": "18f2c3a4b5d6e7f0",
555
+ "subject": "Re: Weekly report",
556
+ "from": "Sam <sam@example.com>",
557
+ "to": "team@example.com",
558
+ "date": "2026-09-11T08:00:00Z",
559
+ "text": "Shipped the weekly report.",
560
+ "truncated": false
561
+ }
562
+ ]
563
+ },
564
+ {
565
+ "id": "18f2c3a4b5d6e7f7",
566
+ "threadId": "18f2c3a4b5d6e7f0",
567
+ "subject": "Weekly report",
568
+ "from": "Jane <jane@example.com>",
569
+ "to": "team@example.com",
570
+ "date": "2026-09-10T08:00:00Z",
571
+ "text": "Draft attached.",
572
+ "truncated": false,
573
+ "attachments": [
574
+ {
575
+ "id": "ANGjdJ8w9h1Q2k3L4m5N6o7P8q9R0s",
576
+ "filename": "weekly-report.pdf",
577
+ "mimeType": "application/pdf",
578
+ "size": 48213
579
+ }
156
580
  ]
157
581
  },
158
- { "id": "18f2c3a4b5d6e7f7", "threadId": "18f2c3a4b5d6e7f0", "subject": "Weekly report", "from": "Jane <jane@example.com>", "to": "team@example.com", "date": "2026-09-10T08:00:00Z", "text": "Draft attached.", "truncated": false, "attachments": [{ "id": "ANGjdJ8w9h1Q2k3L4m5N6o7P8q9R0s", "filename": "weekly-report.pdf", "mimeType": "application/pdf", "size": 48213 }] },
159
- { "filename": "weekly-report.pdf", "mimeType": "application/pdf", "size": 20, "dataBase64": "JVBERi0xLjQKJcOkw7zDtsOfCg==" }
582
+ {
583
+ "filename": "weekly-report.pdf",
584
+ "mimeType": "application/pdf",
585
+ "size": 20,
586
+ "dataBase64": "JVBERi0xLjQKJcOkw7zDtsOfCg=="
587
+ },
588
+ {
589
+ "rows": [
590
+ {
591
+ "week": "2026-W36",
592
+ "total": "1234.50"
593
+ }
594
+ ],
595
+ "truncated": false,
596
+ "sample": true
597
+ }
160
598
  ]
161
599
  }