@celigo/api-specs 0.2.53 → 0.2.54

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.
@@ -0,0 +1,865 @@
1
+ openapi: 3.2.0
2
+ info:
3
+ version: 1.0.0
4
+ title: Storage Query
5
+ description: Run read-only SQL over files in Celigo Storage and page through the results.
6
+ x-celigo-ai-guidance:
7
+ - |-
8
+ API for querying files already in Celigo Storage with SQL. Submit one SELECT with
9
+ `POST /v1/storage/query`, poll `GET /v1/storage/query/{_id}/status` until `status` is
10
+ `completed`, then read rows a page at a time from `GET /v1/storage/query/{_id}/results`.
11
+ Nothing is written to storage; a query can only read files the caller can already read.
12
+ servers:
13
+ - url: https://api.integrator.io
14
+ description: Production (US / default region)
15
+ - url: https://api.eu.integrator.io
16
+ description: Production (EU region)
17
+ - url: https://api.au.integrator.io
18
+ description: Production (AU region)
19
+ - url: https://api.ca.integrator.io
20
+ description: Production (CA region)
21
+ security:
22
+ - bearerAuth: []
23
+ tags:
24
+ - name: Storage Query
25
+ description: |-
26
+ Storage Query runs a single read-only SQL `SELECT` over CSV, JSON, NDJSON, and Parquet files held in Celigo Storage. A file or folder is referenced by its storage path, written where a table name would go (`FROM "orders/2026/september.csv"`) or passed to a reader function such as `read_csv_auto`. Submitting a query validates and authorizes it synchronously, then runs it in the background: poll the job's status until it completes and fetch the rows page by page. The account's license must include the Storage Query entitlement (`filesql`); every call on an account without it answers `403 STORAGE_QUERY_NOT_ENTITLED`.
27
+
28
+ ## Storage query job schema
29
+
30
+ {% openapi-schemas spec="storagequery" schemas="StorageQueryJob" grouped="true" %}
31
+ paths:
32
+ /v1/storage/query:
33
+ post:
34
+ x-internal: false
35
+ operationId: submitStorageQuery
36
+ tags:
37
+ - Storage Query
38
+ summary: Submit a storage query
39
+ description: |-
40
+ Validates one read-only SQL `SELECT`, resolves every storage path it references
41
+ with the caller's own permissions, and queues it for execution. The response is
42
+ the new job in `queued` state; poll `GET /v1/storage/query/{_id}/status` until it
43
+ is `completed`, then read rows from `GET /v1/storage/query/{_id}/results`.
44
+
45
+ Everything that can be checked before running is checked here and answered
46
+ synchronously, and a rejected submit creates no job: the statement must parse, be
47
+ exactly one `SELECT`, use only allow-listed functions, reference files only through
48
+ bare storage paths or the storage reader functions, and every path must resolve to
49
+ a file — or a folder of same-format files — the caller can read. A statement that
50
+ references no file is accepted only when it is a pure constant expression. Supported
51
+ file formats are CSV/TSV, JSON, NDJSON/JSONL, and Parquet; the reader is chosen from
52
+ the file's extension (or its MIME type), and an explicit reader function must match
53
+ it.
54
+
55
+ Read options are named arguments of the reader call, checked against a per-reader
56
+ allowlist — for `read_csv`/`read_csv_auto`: `header`, `delim`, `quote`, `escape`,
57
+ `sample_size`, `types`, `names`, `dateformat`, `timestampformat`, `ignore_errors`,
58
+ `null_padding`, `all_varchar`, `nullstr`, `allow_quoted_nulls`, `compression`,
59
+ `union_by_name`; for the JSON and NDJSON readers: `sample_size`, `ignore_errors`,
60
+ `dateformat`, `timestampformat`, `map_inference_threshold`, `maximum_depth`,
61
+ `maximum_sample_files`, `maximum_object_size`, `columns`, `format`, `records`,
62
+ `convert_strings_to_integers`, `compression`, `union_by_name`; for `read_parquet`:
63
+ `union_by_name`. Option values must be literals.
64
+
65
+ Submissions are rate-limited per account; over the limit the route answers
66
+ `429 STORAGE_QUERY_SUBMIT_RATE_LIMITED` with a `Retry-After` header, and every
67
+ submit — accepted or rejected — counts toward it. The number of distinct files a
68
+ statement may reference, the number of files a referenced folder may hold, and the
69
+ total bytes a statement may read are each capped; the 422 that reports an exceeded
70
+ cap names the current limit. Requires the account's license to include the Storage
71
+ Query entitlement (`filesql`).
72
+ requestBody:
73
+ required: true
74
+ content:
75
+ application/json:
76
+ schema:
77
+ $ref: '#/components/schemas/StorageQueryRequest'
78
+ examples:
79
+ filePath:
80
+ summary: Aggregate a CSV file by storage path
81
+ value:
82
+ sql: SELECT customer_id, SUM(total) AS spend FROM "orders/2026/september.csv" GROUP BY customer_id ORDER BY spend DESC LIMIT 100
83
+ readerOptions:
84
+ summary: Read a semicolon-delimited CSV through a reader function
85
+ value:
86
+ sql: SELECT * FROM read_csv_auto('exports/inventory.csv', header = true, delim = ';') WHERE quantity < 10
87
+ constant:
88
+ summary: Constant expression (no file) — connectivity check
89
+ value:
90
+ sql: SELECT 1 AS one, 'a' AS letter, 2.5 AS num, TRUE AS flag
91
+ responses:
92
+ '202':
93
+ description: Query accepted and queued. Poll the status route with `jobId`.
94
+ content:
95
+ application/json:
96
+ schema:
97
+ type: object
98
+ required:
99
+ - jobId
100
+ - status
101
+ properties:
102
+ jobId:
103
+ type: string
104
+ format: objectId
105
+ description: Identifier of the new job — the `{_id}` for the status and results routes.
106
+ examples:
107
+ - 6ab5a7d0c772d334c44701be
108
+ status:
109
+ type: string
110
+ enum:
111
+ - queued
112
+ x-enumDescriptions:
113
+ queued: The only state a submit returns; execution has not started yet.
114
+ description: Initial lifecycle state of the job.
115
+ examples:
116
+ default:
117
+ value:
118
+ jobId: 6ab5a7d0c772d334c44701be
119
+ status: queued
120
+ '400':
121
+ description: |-
122
+ The body or the statement is malformed: `sql` is missing or not a non-empty
123
+ string (`STORAGE_QUERY_SQL_REQUIRED`), the statement does not parse
124
+ (`STORAGE_QUERY_INVALID_SQL` — the message carries the parser's position), or it
125
+ exceeds the size cap (`STORAGE_QUERY_SQL_TOO_LARGE`).
126
+ content:
127
+ application/json:
128
+ schema:
129
+ $ref: '#/components/schemas/Error'
130
+ examples:
131
+ sqlRequired:
132
+ summary: Missing or non-string sql
133
+ value:
134
+ errors:
135
+ - code: STORAGE_QUERY_SQL_REQUIRED
136
+ message: sql is required and must be a non-empty string
137
+ invalidSql:
138
+ summary: Statement does not parse
139
+ value:
140
+ errors:
141
+ - code: STORAGE_QUERY_INVALID_SQL
142
+ message: syntax error at or near "SELEC"
143
+ '401':
144
+ $ref: '#/components/responses/401-unauthorized'
145
+ '403':
146
+ description: |-
147
+ The account's license does not include the Storage Query entitlement
148
+ (`STORAGE_QUERY_NOT_ENTITLED`). Also returned when the caller's role,
149
+ environment, or account-share context does not permit the query.
150
+ content:
151
+ application/json:
152
+ schema:
153
+ $ref: '#/components/schemas/Error'
154
+ examples:
155
+ notEntitled:
156
+ value:
157
+ errors:
158
+ - code: STORAGE_QUERY_NOT_ENTITLED
159
+ message: Storage query is not enabled for this account
160
+ '404':
161
+ description: |-
162
+ A referenced storage path did not resolve to a file the caller can read
163
+ (`STORAGE_QUERY_SOURCE_NOT_FOUND`). A path outside the caller's reach looks
164
+ exactly like a missing one.
165
+ content:
166
+ application/json:
167
+ schema:
168
+ $ref: '#/components/schemas/Error'
169
+ examples:
170
+ sourceNotFound:
171
+ value:
172
+ errors:
173
+ - code: STORAGE_QUERY_SOURCE_NOT_FOUND
174
+ message: No storage file found at path "orders/2026/september.csv"
175
+ '422':
176
+ description: |-
177
+ The statement parsed but is outside the supported surface. As-built cases:
178
+ not a `SELECT` (`STORAGE_QUERY_NOT_SELECT`); more than one statement
179
+ (`STORAGE_QUERY_MULTIPLE_STATEMENTS`); a table function other than the storage
180
+ readers, `unnest`, `generate_series`, or `range`
181
+ (`STORAGE_QUERY_TABLE_FUNCTION_NOT_ALLOWED`); a scalar function outside the
182
+ allowlist (`STORAGE_QUERY_FUNCTION_NOT_ALLOWED`); a reader option the reader does
183
+ not accept, or a positional option (`STORAGE_QUERY_INVALID_READ_OPTION`); a reader
184
+ whose first argument is not a literal path or list of paths
185
+ (`STORAGE_QUERY_READER_PATH_NOT_LITERAL`); a reader that does not match the
186
+ file's format (`STORAGE_QUERY_READER_FORMAT_MISMATCH`); a row generator with no
187
+ file reference (`STORAGE_QUERY_NO_STORAGE_REFERENCE`) or one that would generate
188
+ more rows than allowed (`STORAGE_QUERY_GENERATOR_TOO_LARGE`); a schema- or
189
+ catalog-qualified table name (`STORAGE_QUERY_INVALID_SOURCE`); an unsupported
190
+ file type (`STORAGE_QUERY_UNSUPPORTED_FILE_TYPE`); a folder that is empty, mixes
191
+ formats, or holds too many files (`STORAGE_QUERY_FOLDER_EMPTY`,
192
+ `STORAGE_QUERY_MIXED_FORMAT_FOLDER`, `STORAGE_QUERY_FOLDER_TOO_MANY_FILES`); too
193
+ many distinct files (`STORAGE_QUERY_TOO_MANY_SOURCES`); or more input bytes than
194
+ the cap (`STORAGE_QUERY_INPUT_TOO_LARGE`).
195
+ content:
196
+ application/json:
197
+ schema:
198
+ $ref: '#/components/schemas/Error'
199
+ examples:
200
+ notSelect:
201
+ summary: Statement is not a SELECT
202
+ value:
203
+ errors:
204
+ - code: STORAGE_QUERY_NOT_SELECT
205
+ message: Only SELECT statements are supported
206
+ multipleStatements:
207
+ summary: More than one statement
208
+ value:
209
+ errors:
210
+ - code: STORAGE_QUERY_MULTIPLE_STATEMENTS
211
+ message: Exactly one SQL statement is supported per request
212
+ tableFunctionNotAllowed:
213
+ summary: Table function outside the storage readers
214
+ value:
215
+ errors:
216
+ - code: STORAGE_QUERY_TABLE_FUNCTION_NOT_ALLOWED
217
+ message: Table functions are not allowed; reference Celigo Storage file paths instead
218
+ functionNotAllowed:
219
+ summary: Scalar function outside the allowlist
220
+ value:
221
+ errors:
222
+ - code: STORAGE_QUERY_FUNCTION_NOT_ALLOWED
223
+ message: Function "version" is not allowed
224
+ invalidReadOption:
225
+ summary: Reader option the reader does not accept
226
+ value:
227
+ errors:
228
+ - code: STORAGE_QUERY_INVALID_READ_OPTION
229
+ message: Option "foo" is not supported for read_csv_auto
230
+ noStorageReference:
231
+ summary: Row generator without a file reference
232
+ value:
233
+ errors:
234
+ - code: STORAGE_QUERY_NO_STORAGE_REFERENCE
235
+ message: A query that generates rows must read at least one Celigo Storage file; only constant expressions may omit a file reference
236
+ '429':
237
+ description: |-
238
+ Too many submits for this account in the current window
239
+ (`STORAGE_QUERY_SUBMIT_RATE_LIMITED`). Wait for the number of seconds in the
240
+ `Retry-After` header before submitting again.
241
+ headers:
242
+ Retry-After:
243
+ description: Seconds to wait before the next submit.
244
+ schema:
245
+ type: integer
246
+ content:
247
+ application/json:
248
+ schema:
249
+ $ref: '#/components/schemas/Error'
250
+ examples:
251
+ submitRateLimited:
252
+ value:
253
+ errors:
254
+ - code: STORAGE_QUERY_SUBMIT_RATE_LIMITED
255
+ message: Too many queries submitted for this account; retry after 42 seconds
256
+ x-celigo-ai-guidance:
257
+ - |-
258
+ A 202 means only that the statement was accepted; the rows come from the status
259
+ and results routes. Poll GET /v1/storage/query/{jobId}/status until status is
260
+ completed — a results request on a queued or running job answers 409
261
+ STORAGE_QUERY_JOB_NOT_READY.
262
+ - |-
263
+ A 4xx from this route carries no jobId, so there is nothing to poll after a
264
+ rejected submit; fix the statement and resubmit. Read options such as header = true
265
+ or delim = ';' are accepted as named arguments of read_csv_auto — the submit only
266
+ fails later, on path resolution, if the file does not exist.
267
+ /v1/storage/query/{_id}/status:
268
+ get:
269
+ x-internal: false
270
+ operationId: getStorageQueryStatus
271
+ tags:
272
+ - Storage Query
273
+ summary: Get a storage query job's status
274
+ description: |-
275
+ Returns the job's lifecycle state and timestamps. Once `status` is `completed` the
276
+ response also carries the result manifest — `rowCount`, `pageCount`, `truncated`,
277
+ `columns`, and `executionMs` — which is everything needed to page through
278
+ `GET /v1/storage/query/{_id}/results`. A `failed` job carries `error` instead.
279
+ Jobs are scoped to the submitting account: another account's job, or one that has
280
+ expired, answers 404 exactly like an unknown id. Requires the account's license to
281
+ include the Storage Query entitlement (`filesql`).
282
+ parameters:
283
+ - name: _id
284
+ in: path
285
+ required: true
286
+ description: The `jobId` returned by `POST /v1/storage/query`.
287
+ schema:
288
+ type: string
289
+ format: objectId
290
+ examples:
291
+ - 6ab5a7d0c772d334c44701be
292
+ responses:
293
+ '200':
294
+ description: Current state of the job.
295
+ content:
296
+ application/json:
297
+ schema:
298
+ $ref: '#/components/schemas/StorageQueryJob'
299
+ examples:
300
+ completed:
301
+ summary: Completed — manifest present
302
+ value:
303
+ jobId: 6ab5a7d0c772d334c44701be
304
+ status: completed
305
+ createdAt: '2026-09-24T22:44:32.845Z'
306
+ startedAt: '2026-09-24T22:44:32.927Z'
307
+ completedAt: '2026-09-24T22:44:33.004Z'
308
+ executionMs: 67
309
+ rowCount: 1
310
+ truncated: false
311
+ pageCount: 1
312
+ columns:
313
+ - name: one
314
+ type: INTEGER
315
+ - name: letter
316
+ type: VARCHAR
317
+ - name: num
318
+ type: DECIMAL(2,1)
319
+ - name: flag
320
+ type: BOOLEAN
321
+ completedEmpty:
322
+ summary: Completed with no matching rows
323
+ value:
324
+ jobId: 6ab5a7d2c772d334c44701c6
325
+ status: completed
326
+ createdAt: '2026-09-24T22:44:34.948Z'
327
+ startedAt: '2026-09-24T22:44:34.962Z'
328
+ completedAt: '2026-09-24T22:44:34.982Z'
329
+ executionMs: 5
330
+ rowCount: 0
331
+ truncated: false
332
+ pageCount: 0
333
+ columns:
334
+ - name: one
335
+ type: INTEGER
336
+ queued:
337
+ summary: Still waiting for a worker
338
+ value:
339
+ jobId: 6ab5a84349aea63c4022909e
340
+ status: queued
341
+ createdAt: '2026-09-24T22:46:27.239Z'
342
+ '400':
343
+ description: The path segment is not a valid job identifier (`STORAGE_QUERY_INVALID_JOB_ID`).
344
+ content:
345
+ application/json:
346
+ schema:
347
+ $ref: '#/components/schemas/Error'
348
+ examples:
349
+ invalidJobId:
350
+ value:
351
+ errors:
352
+ - code: STORAGE_QUERY_INVALID_JOB_ID
353
+ message: jobId "not-an-id" is not a valid identifier
354
+ '401':
355
+ $ref: '#/components/responses/401-unauthorized'
356
+ '403':
357
+ description: The account's license does not include the Storage Query entitlement (`STORAGE_QUERY_NOT_ENTITLED`).
358
+ content:
359
+ application/json:
360
+ schema:
361
+ $ref: '#/components/schemas/Error'
362
+ examples:
363
+ notEntitled:
364
+ value:
365
+ errors:
366
+ - code: STORAGE_QUERY_NOT_ENTITLED
367
+ message: Storage query is not enabled for this account
368
+ '404':
369
+ description: No job with this id is visible to the caller (`STORAGE_QUERY_JOB_NOT_FOUND`) — unknown, expired, or submitted by another account.
370
+ content:
371
+ application/json:
372
+ schema:
373
+ $ref: '#/components/schemas/Error'
374
+ examples:
375
+ jobNotFound:
376
+ value:
377
+ errors:
378
+ - code: STORAGE_QUERY_JOB_NOT_FOUND
379
+ message: No query job found with id "000000000000000000000000"
380
+ '429':
381
+ description: Too many status or results reads for this account (`STORAGE_QUERY_RATE_LIMITED`). Wait for the seconds in `Retry-After`.
382
+ headers:
383
+ Retry-After:
384
+ description: Seconds to wait before the next read.
385
+ schema:
386
+ type: integer
387
+ content:
388
+ application/json:
389
+ schema:
390
+ $ref: '#/components/schemas/Error'
391
+ examples:
392
+ rateLimited:
393
+ value:
394
+ errors:
395
+ - code: STORAGE_QUERY_RATE_LIMITED
396
+ message: Too many requests for this account; retry after 1 seconds
397
+ /v1/storage/query/{_id}/results:
398
+ get:
399
+ x-internal: false
400
+ operationId: getStorageQueryResults
401
+ tags:
402
+ - Storage Query
403
+ summary: Get a page of storage query results
404
+ description: |-
405
+ Returns one page of a completed job's rows. Pages run from 1 to the job's
406
+ `pageCount`; omit `page` for the first one and keep requesting `page + 1` while
407
+ `hasMore` is true. A completed job that matched nothing has `pageCount` 0 and still
408
+ serves page 1 as an empty page, so an empty result set never looks like a bad
409
+ request. Rows exist only for a `completed` job: a `queued` or `running` job answers
410
+ 409 until it finishes, and a `failed` job answers 409 permanently — read its `error`
411
+ from the status route instead. Jobs are scoped to the submitting account, and an
412
+ expired job answers 404. Requires the account's license to include the Storage
413
+ Query entitlement (`filesql`).
414
+ parameters:
415
+ - name: _id
416
+ in: path
417
+ required: true
418
+ description: The `jobId` returned by `POST /v1/storage/query`.
419
+ schema:
420
+ type: string
421
+ format: objectId
422
+ examples:
423
+ - 6ab5a7d0c772d334c44701be
424
+ - name: page
425
+ in: query
426
+ required: false
427
+ description: |-
428
+ Page to return, from 1 to the job's `pageCount`. Defaults to 1 when omitted.
429
+ Anything that is not a positive integer within range — `0`, a non-numeric
430
+ value, or a number past `pageCount` — answers 400 rather than being coerced.
431
+ schema:
432
+ type: integer
433
+ minimum: 1
434
+ default: 1
435
+ examples:
436
+ - 1
437
+ responses:
438
+ '200':
439
+ description: One page of rows.
440
+ content:
441
+ application/json:
442
+ schema:
443
+ $ref: '#/components/schemas/StorageQueryResultsPage'
444
+ examples:
445
+ singlePage:
446
+ summary: Single-page result set
447
+ value:
448
+ page: 1
449
+ pageCount: 1
450
+ rowCount: 1
451
+ hasMore: false
452
+ rows:
453
+ - one: 1
454
+ letter: a
455
+ num: '2.5'
456
+ flag: true
457
+ empty:
458
+ summary: Page 1 of a job that matched no rows
459
+ value:
460
+ page: 1
461
+ pageCount: 0
462
+ rowCount: 0
463
+ hasMore: false
464
+ rows: []
465
+ '400':
466
+ description: |-
467
+ `page` is not a positive integer within `1..pageCount`
468
+ (`STORAGE_QUERY_PAGE_OUT_OF_RANGE` — the message names the job's page count),
469
+ or the path segment is not a valid job identifier (`STORAGE_QUERY_INVALID_JOB_ID`).
470
+ content:
471
+ application/json:
472
+ schema:
473
+ $ref: '#/components/schemas/Error'
474
+ examples:
475
+ pageOutOfRange:
476
+ value:
477
+ errors:
478
+ - code: STORAGE_QUERY_PAGE_OUT_OF_RANGE
479
+ message: page "2" is out of range; this job has 1 result page(s)
480
+ invalidJobId:
481
+ value:
482
+ errors:
483
+ - code: STORAGE_QUERY_INVALID_JOB_ID
484
+ message: jobId "not-an-id" is not a valid identifier
485
+ '401':
486
+ $ref: '#/components/responses/401-unauthorized'
487
+ '403':
488
+ description: The account's license does not include the Storage Query entitlement (`STORAGE_QUERY_NOT_ENTITLED`).
489
+ content:
490
+ application/json:
491
+ schema:
492
+ $ref: '#/components/schemas/Error'
493
+ examples:
494
+ notEntitled:
495
+ value:
496
+ errors:
497
+ - code: STORAGE_QUERY_NOT_ENTITLED
498
+ message: Storage query is not enabled for this account
499
+ '404':
500
+ description: No job with this id is visible to the caller (`STORAGE_QUERY_JOB_NOT_FOUND`) — unknown, expired, or submitted by another account.
501
+ content:
502
+ application/json:
503
+ schema:
504
+ $ref: '#/components/schemas/Error'
505
+ examples:
506
+ jobNotFound:
507
+ value:
508
+ errors:
509
+ - code: STORAGE_QUERY_JOB_NOT_FOUND
510
+ message: No query job found with id "000000000000000000000000"
511
+ '409':
512
+ description: |-
513
+ The job has not produced rows: it is still `queued` or `running`, or it `failed`
514
+ (`STORAGE_QUERY_JOB_NOT_READY` — the message names the current status). Poll the
515
+ status route; retry here only once it reports `completed`.
516
+ content:
517
+ application/json:
518
+ schema:
519
+ $ref: '#/components/schemas/Error'
520
+ examples:
521
+ notReady:
522
+ value:
523
+ errors:
524
+ - code: STORAGE_QUERY_JOB_NOT_READY
525
+ message: Query job "6ab5a84349aea63c4022909e" is "running"; results are available only once it has completed
526
+ '429':
527
+ description: Too many status or results reads for this account (`STORAGE_QUERY_RATE_LIMITED`). Wait for the seconds in `Retry-After`.
528
+ headers:
529
+ Retry-After:
530
+ description: Seconds to wait before the next read.
531
+ schema:
532
+ type: integer
533
+ content:
534
+ application/json:
535
+ schema:
536
+ $ref: '#/components/schemas/Error'
537
+ examples:
538
+ rateLimited:
539
+ value:
540
+ errors:
541
+ - code: STORAGE_QUERY_RATE_LIMITED
542
+ message: Too many requests for this account; retry after 1 seconds
543
+ x-celigo-ai-guidance:
544
+ - |-
545
+ Read pageCount from the completed status first, then fetch pages 1..pageCount; a
546
+ page past the end answers 400 STORAGE_QUERY_PAGE_OUT_OF_RANGE. When pageCount is 0
547
+ the result set is empty — page 1 returns rows: [] and there is nothing else to fetch.
548
+ components:
549
+ securitySchemes:
550
+ bearerAuth:
551
+ type: http
552
+ scheme: bearer
553
+ schemas:
554
+ StorageQueryRequest:
555
+ type: object
556
+ description: |-
557
+ One read-only SQL statement to run over files in Celigo Storage. The body carries
558
+ nothing else — reader options such as CSV delimiters belong inside the SQL, as
559
+ named arguments of the reader function that reads the file.
560
+ required:
561
+ - sql
562
+ properties:
563
+ sql:
564
+ type: string
565
+ description: |-
566
+ A single `SELECT` statement. Storage files are its tables: write a file or
567
+ folder path where a table name would go, quoted as an identifier
568
+ (`FROM "orders/2026/september.csv"`), or pass the path as the first, literal
569
+ argument of a reader function (`read_csv_auto`, `read_csv`, `read_json_auto`,
570
+ `read_json`, `read_ndjson_auto`, `read_ndjson`, `read_parquet`) when the file
571
+ needs explicit read options. Paths are relative to the account's storage root.
572
+ Anything other than one `SELECT` — an `UPDATE`, two statements, a table function
573
+ that is not a storage reader, or a function outside the allowlist — is rejected
574
+ at submit with a 4xx and creates no job. A statement that references no file is
575
+ accepted only when it is a pure constant expression.
576
+ examples:
577
+ - SELECT customer_id, SUM(total) AS spend FROM "orders/2026/september.csv" GROUP BY customer_id ORDER BY spend DESC LIMIT 100
578
+ x-celigo-ai-guidance:
579
+ - |-
580
+ Quote storage paths as identifiers relative to the account root: FROM
581
+ "folder/file.csv". A path that does not resolve fails the submit with 404
582
+ STORAGE_QUERY_SOURCE_NOT_FOUND and the response carries no jobId.
583
+ - |-
584
+ Put read options inside the SQL as named arguments of the reader call, e.g.
585
+ read_csv_auto('folder/file.csv', header = true, delim = ';'). An option the reader
586
+ does not accept fails the submit with 422 STORAGE_QUERY_INVALID_READ_OPTION naming
587
+ the option and the function.
588
+ - |-
589
+ A row generator such as generate_series is accepted only alongside at least one
590
+ storage file reference; on its own it fails the submit with 422
591
+ STORAGE_QUERY_NO_STORAGE_REFERENCE. A constant SELECT with no FROM (SELECT 1 AS one)
592
+ is accepted and completes in well under a second — useful as a connectivity check.
593
+ Error:
594
+ type: object
595
+ description: Standard error response envelope returned by integrator.io APIs.
596
+ properties:
597
+ errors:
598
+ type: array
599
+ description: List of errors that occurred while processing the request.
600
+ items:
601
+ type: object
602
+ properties:
603
+ code:
604
+ oneOf:
605
+ - type: string
606
+ - type: integer
607
+ description: |-
608
+ Machine-readable error code. Usually a string like
609
+ `invalid_ref`, `missing_required_field`, or `unauthorized`;
610
+ may be an **integer** when the error mirrors an upstream HTTP
611
+ status (e.g. `500`) — most commonly returned by connection-ping
612
+ and adaptor-proxy responses.
613
+ message:
614
+ type: string
615
+ description: Human-readable description of the error.
616
+ field:
617
+ type: string
618
+ description: |-
619
+ Optional pointer to the document field that caused the error.
620
+ Used by structural validation errors (`missing_required_field`,
621
+ `invalid_ref`) to indicate which field is at fault
622
+ (e.g. `_id`, `type`, `http.baseURI`).
623
+ source:
624
+ type: string
625
+ description: |-
626
+ Optional origin layer for the error — e.g. `application` when
627
+ the error came from the remote system the adaptor called,
628
+ `connector` when the adaptor itself rejected the request.
629
+ required:
630
+ - message
631
+ required:
632
+ - errors
633
+ StorageQueryJob:
634
+ type: object
635
+ description: |-
636
+ A submitted query and its progress. Created by `POST /v1/storage/query`, read from
637
+ `GET /v1/storage/query/{_id}/status`. The result manifest (`rowCount`, `pageCount`,
638
+ `columns`, …) appears once the job completes; rows are fetched separately from
639
+ `GET /v1/storage/query/{_id}/results`. Jobs are visible only to the account that
640
+ submitted them and expire on their own after a retention period, after which the
641
+ status and results routes answer 404.
642
+ required:
643
+ - jobId
644
+ - status
645
+ - createdAt
646
+ properties:
647
+ jobId:
648
+ type: string
649
+ format: objectId
650
+ readOnly: true
651
+ description: Identifier of the query job. Use it as `{_id}` on the status and results routes.
652
+ examples:
653
+ - 6ab5a7d0c772d334c44701be
654
+ status:
655
+ type: string
656
+ enum:
657
+ - queued
658
+ - running
659
+ - completed
660
+ - failed
661
+ x-enumDescriptions:
662
+ queued: Accepted and waiting for a worker; the results route answers 409 until the job completes.
663
+ running: A worker is executing the statement; the results route still answers 409.
664
+ completed: Rows are available — read `pageCount` and fetch pages from the results route.
665
+ failed: The query did not produce a result; `error` explains why. There are no pages to fetch.
666
+ description: |-
667
+ Lifecycle of the job. Every job starts `queued` (the submit response) and moves
668
+ to `running` when a worker claims it, then to `completed` or `failed`; there is
669
+ no cancel. Constant queries usually complete within a few hundred milliseconds of
670
+ submission, so a status read straight after the submit may already show
671
+ `completed`.
672
+ examples:
673
+ - completed
674
+ createdAt:
675
+ type: string
676
+ format: date-time
677
+ readOnly: true
678
+ description: Timestamp when the submit accepted the query.
679
+ examples:
680
+ - '2026-09-24T22:44:32.845Z'
681
+ startedAt:
682
+ type: string
683
+ format: date-time
684
+ readOnly: true
685
+ description: Timestamp when a worker began executing the statement. Absent while the job is `queued`.
686
+ examples:
687
+ - '2026-09-24T22:44:32.927Z'
688
+ completedAt:
689
+ type: string
690
+ format: date-time
691
+ readOnly: true
692
+ description: Timestamp when the job reached `completed` or `failed`. Absent until then.
693
+ examples:
694
+ - '2026-09-24T22:44:33.004Z'
695
+ executionMs:
696
+ type: integer
697
+ minimum: 0
698
+ readOnly: true
699
+ description: Only present when `status` is `completed`. Milliseconds the statement took to execute, excluding time spent queued.
700
+ examples:
701
+ - 67
702
+ rowCount:
703
+ type: integer
704
+ minimum: 0
705
+ readOnly: true
706
+ description: |-
707
+ Only present when `status` is `completed`. Total rows in the result set across
708
+ all pages; 0 when the query matched nothing, in which case `pageCount` is also 0
709
+ and page 1 of the results route returns an empty page.
710
+ examples:
711
+ - 1
712
+ truncated:
713
+ type: boolean
714
+ readOnly: true
715
+ description: |-
716
+ Only present when `status` is `completed`. When true, the result set hit the
717
+ service's row cap and `rowCount` counts only the rows that were kept; narrow the
718
+ query (a `WHERE`, or a `LIMIT` with `ORDER BY`) to see the rest.
719
+ examples:
720
+ - false
721
+ pageCount:
722
+ type: integer
723
+ minimum: 0
724
+ readOnly: true
725
+ description: Only present when `status` is `completed`. Number of result pages to fetch, numbered from 1; 0 for an empty result set.
726
+ examples:
727
+ - 1
728
+ columns:
729
+ type: array
730
+ readOnly: true
731
+ description: |-
732
+ Only present when `status` is `completed`. Result columns in `SELECT` order, each
733
+ with the engine's type name for the column — the key each row object uses.
734
+ Present, and possibly non-empty, even when `rowCount` is 0.
735
+ items:
736
+ type: object
737
+ required:
738
+ - name
739
+ - type
740
+ properties:
741
+ name:
742
+ type: string
743
+ description: Column name as projected by the statement (the alias when one was given).
744
+ examples:
745
+ - spend
746
+ type:
747
+ type: string
748
+ description: |-
749
+ SQL type of the column as reported by the engine, for example `INTEGER`,
750
+ `VARCHAR`, `BOOLEAN`, `DECIMAL(2,1)`, or `TIMESTAMP`. Parameterized types
751
+ carry their parameters, so treat the value as free text rather than a fixed
752
+ set.
753
+ examples:
754
+ - DECIMAL(2,1)
755
+ error:
756
+ type: object
757
+ readOnly: true
758
+ description: |-
759
+ Only present when `status` is `failed`. `code` names the failure class — for
760
+ example `STORAGE_QUERY_TIMEOUT` when the statement exceeded the execution
761
+ budget, `STORAGE_QUERY_EXECUTION_FAILED` when the engine rejected it while
762
+ running, or `STORAGE_QUERY_JOB_INTERRUPTED` when the worker holding it went away
763
+ (resubmit the same statement) — and `message` explains it.
764
+ required:
765
+ - code
766
+ - message
767
+ properties:
768
+ code:
769
+ type: string
770
+ description: Machine-readable failure code.
771
+ examples:
772
+ - STORAGE_QUERY_TIMEOUT
773
+ message:
774
+ type: string
775
+ description: Human-readable explanation of the failure.
776
+ examples:
777
+ - Query exceeded the maximum execution time of 300 seconds
778
+ StorageQueryResultsPage:
779
+ type: object
780
+ description: |-
781
+ One page of a completed job's rows, as returned by
782
+ `GET /v1/storage/query/{_id}/results?page=N`. Pages are numbered from 1 up to the
783
+ job's `pageCount`; fetch them in turn until `hasMore` is false.
784
+ required:
785
+ - page
786
+ - pageCount
787
+ - rowCount
788
+ - hasMore
789
+ - rows
790
+ properties:
791
+ page:
792
+ type: integer
793
+ minimum: 1
794
+ description: Page number served. 1 when the `page` query parameter was omitted.
795
+ examples:
796
+ - 1
797
+ pageCount:
798
+ type: integer
799
+ minimum: 0
800
+ description: Total pages in the result set — the same value as `pageCount` on the job's status. 0 when the query matched nothing.
801
+ examples:
802
+ - 1
803
+ rowCount:
804
+ type: integer
805
+ minimum: 0
806
+ description: Number of rows on this page (not the job-wide total the status route reports).
807
+ examples:
808
+ - 1
809
+ hasMore:
810
+ type: boolean
811
+ description: When true, a further page exists — request `page + 1`. False on the last page and on an empty result set.
812
+ examples:
813
+ - false
814
+ rows:
815
+ type: array
816
+ description: |-
817
+ Rows on this page, in the statement's output order. Each row is an object keyed
818
+ by column name (see `columns` on the job's status). Integer and boolean columns
819
+ arrive as JSON numbers and booleans; `DECIMAL` values arrive as strings so no
820
+ precision is lost. Empty on an empty result set.
821
+ items:
822
+ type: object
823
+ additionalProperties: true
824
+ examples:
825
+ - - one: 1
826
+ letter: a
827
+ num: '2.5'
828
+ flag: true
829
+ responses:
830
+ 401-unauthorized:
831
+ description: |-
832
+ Unauthorized. The request lacks a valid bearer token, or the provided token
833
+ failed to authenticate.
834
+
835
+ Note: the 401 response is produced by the auth middleware **before** the
836
+ request reaches the endpoint handler, so it does **not** follow the
837
+ standard `{errors: [...]}` envelope. Instead the body is a bare
838
+ `{message: string}` object with no `code`, no `errors` array. Callers
839
+ handling 401s should key off the HTTP status and the `message` string,
840
+ not try to destructure an `errors[]`.
841
+ content:
842
+ application/json:
843
+ schema:
844
+ type: object
845
+ properties:
846
+ message:
847
+ type: string
848
+ description: |-
849
+ Human-readable description of the auth failure. Known values:
850
+ - `"Unauthorized"` — no `Authorization` header on the request.
851
+ - `"Bearer Authentication Failed"` — header present but token
852
+ is invalid, revoked, or expired.
853
+ required:
854
+ - message
855
+ examples:
856
+ missing_token:
857
+ summary: No Authorization header sent
858
+ value:
859
+ message: Unauthorized
860
+ invalid_token:
861
+ summary: Bearer token invalid or revoked
862
+ value:
863
+ message: Bearer Authentication Failed
864
+ x-internal: false
865
+ x-enable-proxy: true
@@ -131,6 +131,8 @@ paths:
131
131
  enabled: true
132
132
  topicsAllowed: 20
133
133
  retentionCeilingDays: 90
134
+ filesql:
135
+ enabled: true
134
136
  lookupCacheUsage:
135
137
  numUnits: 100000000
136
138
  numAddOnUnits: 0
@@ -761,6 +763,23 @@ components:
761
763
  description: Additional lookup-cache units per month the customer purchased as add-ons.
762
764
  examples:
763
765
  - 0
766
+ filesql:
767
+ type: object
768
+ description: |-
769
+ Storage Query entitlement — running SQL over files in Celigo Storage through
770
+ `POST /v1/storage/query`. Present on account-level licenses once the add-on has
771
+ been provisioned; absent otherwise.
772
+ required:
773
+ - enabled
774
+ properties:
775
+ enabled:
776
+ type: boolean
777
+ description: |-
778
+ When true, the account may submit storage queries. When false or when the
779
+ block is absent, every `/v1/storage/query` route answers
780
+ `403 STORAGE_QUERY_NOT_ENTITLED`.
781
+ examples:
782
+ - true
764
783
  di:
765
784
  type: object
766
785
  description: Data Interchange (DI) entitlements.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celigo/api-specs",
3
- "version": "0.2.53",
3
+ "version": "0.2.54",
4
4
  "private": false,
5
5
  "description": "Public OpenAPI bundles (dist/) and the celigo-cli lint schema pack (schemas.json).",
6
6
  "keywords": [
package/schemas.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "provenance": {
3
3
  "repo": "celigo/integrator-api-specs",
4
- "iasCommit": "5cccadb",
4
+ "iasCommit": "eca1253",
5
5
  "generatedAt": "2026-09-24"
6
6
  },
7
7
  "roots": {