@epilot/file-client 1.21.0 → 1.22.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/dist/openapi.json CHANGED
@@ -2,29 +2,29 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "File API",
5
- "version": "1.7.0",
6
- "description": "Upload and manage epilot Files\n\n## Changelog\n<a href=\"changelog\">View API Changelog</a>\n"
5
+ "version": "1.9.0",
6
+ "description": "The File API enables you to upload, store, manage, and share files within the epilot platform.\n\n## Key Features\n- **Upload files** to temporary storage and save them permanently as File entities\n- **Generate previews** (thumbnails) for images and documents\n- **Create public links** to share private files externally\n- **Organize files** into collections for better management\n- **Version control** with automatic file versioning on updates\n\n## File Upload Workflow\n1. Call `uploadFileV2` to get a pre-signed S3 URL\n2. Upload your file directly to S3 using the pre-signed URL (PUT request)\n3. Call `saveFileV2` with the S3 reference to create a permanent File entity\n\n## Changelog\n<a href=\"changelog\">View API Changelog</a>\n"
7
7
  },
8
8
  "tags": [
9
9
  {
10
10
  "name": "File",
11
- "description": "Upload and Manage File Entities"
11
+ "description": "Core file operations for uploading, saving, retrieving, and deleting files.\n\nFiles are stored as epilot entities with the `file` schema and support:\n- Multiple versions (each save creates a new version)\n- Custom metadata and tags\n- Relations to other entities (contacts, orders, etc.)\n- Access control (private or public-read)\n"
12
12
  },
13
13
  {
14
14
  "name": "Preview",
15
- "description": "Preview APIs"
15
+ "description": "Generate thumbnail previews for files. Supports images, PDFs, and common document formats.\n\nPreview images are generated on-demand and cached for performance.\nYou can specify custom dimensions using the `w` (width) and `h` (height) parameters.\n"
16
16
  },
17
17
  {
18
18
  "name": "Public Links",
19
- "description": "Create and Manage Public Links for Files"
19
+ "description": "Create shareable public links for private files.\n\nPublic links allow external users to access files without authentication.\nLinks are permanent until revoked and include the filename for user-friendly URLs.\n"
20
20
  },
21
21
  {
22
22
  "name": "Session",
23
- "description": "Session API for cookie authentication"
23
+ "description": "Browser session management for cookie-based authentication.\n\nUse `getSession` to convert a Bearer token into a session cookie. This enables:\n- Direct use of preview URLs in `<img>` tags\n- File downloads without manual token handling\n\n**Typical flow:**\n1. Authenticate and obtain a Bearer token\n2. Call `GET /v1/files/session` with the Bearer token\n3. Subsequent requests use the session cookie automatically\n"
24
24
  },
25
25
  {
26
26
  "name": "Deprecated",
27
- "description": "Deprecated APIs"
27
+ "description": "Legacy API endpoints scheduled for removal.\n\n**Important:** These endpoints will be removed on **2025-06-30**.\nPlease migrate to the v2 equivalents before this date.\n\n| Deprecated Endpoint | Replacement |\n|---------------------|-------------|\n| `POST /v1/files/upload` | `POST /v2/files/upload` |\n| `POST /v1/files` | `POST /v2/files` |\n"
28
28
  },
29
29
  {
30
30
  "name": "file_schema",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  {
35
35
  "name": "File Collections",
36
- "description": "Collection management for organizing files within entities"
36
+ "description": "Organize files into collections (folders) for better management.\n\nCollections can be:\n- **User-scoped**: Personal collections visible only to the creating user\n- **Global**: Shared collections available to all users for a schema\n\nCollections support hierarchical organization with parent-child relationships.\n"
37
37
  }
38
38
  ],
39
39
  "x-tagGroups": [
@@ -117,6 +117,15 @@
117
117
  }
118
118
  }
119
119
  }
120
+ },
121
+ "400": {
122
+ "$ref": "#/components/responses/BadRequestError"
123
+ },
124
+ "401": {
125
+ "$ref": "#/components/responses/UnauthorizedError"
126
+ },
127
+ "500": {
128
+ "$ref": "#/components/responses/InternalServerError"
120
129
  }
121
130
  }
122
131
  }
@@ -144,6 +153,9 @@
144
153
  },
145
154
  {
146
155
  "$ref": "#/components/parameters/DeleteTempFileQueryParam"
156
+ },
157
+ {
158
+ "$ref": "#/components/parameters/VersionOnlyQueryParam"
147
159
  }
148
160
  ],
149
161
  "requestBody": {
@@ -223,6 +235,18 @@
223
235
  }
224
236
  }
225
237
  }
238
+ },
239
+ "400": {
240
+ "$ref": "#/components/responses/BadRequestError"
241
+ },
242
+ "401": {
243
+ "$ref": "#/components/responses/UnauthorizedError"
244
+ },
245
+ "404": {
246
+ "$ref": "#/components/responses/NotFoundError"
247
+ },
248
+ "500": {
249
+ "$ref": "#/components/responses/InternalServerError"
226
250
  }
227
251
  }
228
252
  }
@@ -232,7 +256,7 @@
232
256
  "operationId": "uploadFile",
233
257
  "summary": "uploadFile",
234
258
  "deprecated": true,
235
- "description": "Create pre-signed S3 URL to upload a file to keep temporarily (one week).\n\nUse the saveFile operation to store file file permanently.\n",
259
+ "description": "**DEPRECATED** - Will be removed on **2025-06-30**. Use `POST /v2/files/upload` instead.\n\n## Migration Guide\nReplace calls to this endpoint with `uploadFileV2`:\n\n| v1 Parameter | v2 Parameter | Notes |\n|--------------|--------------|-------|\n| `file_entity_id` | `file_entity_id` | No change |\n\nThe v2 response includes the same fields with improved structure.\n\n---\n\nCreate pre-signed S3 URL to upload a file to keep temporarily (one week).\n\nUse the saveFile operation to store file file permanently.\n",
236
260
  "tags": [
237
261
  "Deprecated"
238
262
  ],
@@ -251,6 +275,14 @@
251
275
  "application/json": {
252
276
  "schema": {
253
277
  "$ref": "#/components/schemas/UploadFilePayload"
278
+ },
279
+ "examples": {
280
+ "Upload a document": {
281
+ "value": {
282
+ "filename": "document.pdf",
283
+ "mime_type": "application/pdf"
284
+ }
285
+ }
254
286
  }
255
287
  }
256
288
  }
@@ -291,6 +323,15 @@
291
323
  }
292
324
  }
293
325
  }
326
+ },
327
+ "400": {
328
+ "$ref": "#/components/responses/BadRequestError"
329
+ },
330
+ "401": {
331
+ "$ref": "#/components/responses/UnauthorizedError"
332
+ },
333
+ "500": {
334
+ "$ref": "#/components/responses/InternalServerError"
294
335
  }
295
336
  }
296
337
  }
@@ -300,7 +341,7 @@
300
341
  "operationId": "saveFile",
301
342
  "summary": "saveFile",
302
343
  "deprecated": true,
303
- "description": "Create / Update a permanent File entity\n\nMakes file object permanent\n\nSaves metadata to file entity\n",
344
+ "description": "**DEPRECATED** - Will be removed on **2025-06-30**. Use `POST /v2/files` instead.\n\n## Migration Guide\nReplace calls to this endpoint with `saveFileV2`:\n\n| v1 Feature | v2 Feature | Notes |\n|------------|------------|-------|\n| `activity_id` param | `activity_id` param | No change |\n| `async` param | `async` param | No change |\n| - | `fill_activity` param | New in v2 |\n| - | `strict` param | New in v2 |\n| - | `delete_temp_file` param | New in v2, defaults to true |\n\nThe v2 endpoint supports additional parameters for better control over file saving behavior.\n\n---\n\nCreate / Update a permanent File entity.\n\nMakes file object permanent and saves metadata to file entity.\n",
304
345
  "tags": [
305
346
  "Deprecated"
306
347
  ],
@@ -310,6 +351,9 @@
310
351
  },
311
352
  {
312
353
  "$ref": "#/components/parameters/AsyncOperationQueryParam"
354
+ },
355
+ {
356
+ "$ref": "#/components/parameters/VersionOnlyQueryParam"
313
357
  }
314
358
  ],
315
359
  "requestBody": {
@@ -317,6 +361,19 @@
317
361
  "application/json": {
318
362
  "schema": {
319
363
  "$ref": "#/components/schemas/SaveFilePayload"
364
+ },
365
+ "examples": {
366
+ "Save file with S3 reference": {
367
+ "value": {
368
+ "filename": "document.pdf",
369
+ "type": "document",
370
+ "access_control": "private",
371
+ "s3ref": {
372
+ "bucket": "epilot-prod-user-content",
373
+ "key": "123/temp/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf"
374
+ }
375
+ }
376
+ }
320
377
  }
321
378
  }
322
379
  }
@@ -331,6 +388,15 @@
331
388
  }
332
389
  }
333
390
  }
391
+ },
392
+ "400": {
393
+ "$ref": "#/components/responses/BadRequestError"
394
+ },
395
+ "401": {
396
+ "$ref": "#/components/responses/UnauthorizedError"
397
+ },
398
+ "500": {
399
+ "$ref": "#/components/responses/InternalServerError"
334
400
  }
335
401
  }
336
402
  }
@@ -378,6 +444,18 @@
378
444
  }
379
445
  }
380
446
  }
447
+ },
448
+ "401": {
449
+ "$ref": "#/components/responses/UnauthorizedError"
450
+ },
451
+ "403": {
452
+ "$ref": "#/components/responses/ForbiddenError"
453
+ },
454
+ "404": {
455
+ "$ref": "#/components/responses/NotFoundError"
456
+ },
457
+ "500": {
458
+ "$ref": "#/components/responses/InternalServerError"
381
459
  }
382
460
  }
383
461
  },
@@ -423,6 +501,18 @@
423
501
  }
424
502
  }
425
503
  }
504
+ },
505
+ "401": {
506
+ "$ref": "#/components/responses/UnauthorizedError"
507
+ },
508
+ "403": {
509
+ "$ref": "#/components/responses/ForbiddenError"
510
+ },
511
+ "404": {
512
+ "$ref": "#/components/responses/NotFoundError"
513
+ },
514
+ "500": {
515
+ "$ref": "#/components/responses/InternalServerError"
426
516
  }
427
517
  }
428
518
  }
@@ -431,7 +521,7 @@
431
521
  "get": {
432
522
  "operationId": "downloadFile",
433
523
  "summary": "downloadFile",
434
- "description": "Generate pre-signed download S3 url for a file",
524
+ "description": "Generate a pre-signed download URL for a file.\n\nThe returned URL is valid for a limited time (typically 15 minutes) and can be used to download the file directly.\n",
435
525
  "tags": [
436
526
  "File"
437
527
  ],
@@ -440,6 +530,7 @@
440
530
  "name": "id",
441
531
  "in": "path",
442
532
  "required": true,
533
+ "description": "The UUID of the file entity",
443
534
  "schema": {
444
535
  "$ref": "#/components/schemas/FileEntityId"
445
536
  }
@@ -447,7 +538,7 @@
447
538
  {
448
539
  "name": "version",
449
540
  "in": "query",
450
- "description": "index of file version",
541
+ "description": "Index of the file version to download (0 = latest)",
451
542
  "schema": {
452
543
  "type": "integer",
453
544
  "default": 0
@@ -456,7 +547,7 @@
456
547
  {
457
548
  "name": "attachment",
458
549
  "in": "query",
459
- "description": "Controls the Content-Disposition header to control browser behaviour. Set to true to trigger download.",
550
+ "description": "Controls the Content-Disposition header. Set to `true` to trigger browser download dialog, `false` to display inline.",
460
551
  "schema": {
461
552
  "type": "boolean",
462
553
  "default": true
@@ -465,7 +556,7 @@
465
556
  ],
466
557
  "responses": {
467
558
  "200": {
468
- "description": "Generated thumbnail image",
559
+ "description": "Pre-signed download URL",
469
560
  "content": {
470
561
  "application/json": {
471
562
  "schema": {
@@ -474,12 +565,28 @@
474
565
  "download_url": {
475
566
  "type": "string",
476
567
  "format": "uri",
568
+ "description": "Pre-signed S3 URL valid for downloading the file",
477
569
  "example": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/temp/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf?AWSParams=123"
478
570
  }
479
571
  }
572
+ },
573
+ "example": {
574
+ "download_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
480
575
  }
481
576
  }
482
577
  }
578
+ },
579
+ "401": {
580
+ "$ref": "#/components/responses/UnauthorizedError"
581
+ },
582
+ "403": {
583
+ "$ref": "#/components/responses/ForbiddenError"
584
+ },
585
+ "404": {
586
+ "$ref": "#/components/responses/NotFoundError"
587
+ },
588
+ "500": {
589
+ "$ref": "#/components/responses/InternalServerError"
483
590
  }
484
591
  }
485
592
  }
@@ -488,7 +595,7 @@
488
595
  "post": {
489
596
  "operationId": "downloadS3File",
490
597
  "summary": "downloadS3File",
491
- "description": "Generate pre-signed download S3 url for a file",
598
+ "description": "Generate a pre-signed download URL for a file using its S3 reference.\n\nUse this endpoint when you have the S3 bucket and key but not the file entity ID.\n",
492
599
  "tags": [
493
600
  "File"
494
601
  ],
@@ -497,22 +604,26 @@
497
604
  "name": "s3_key",
498
605
  "in": "query",
499
606
  "required": true,
607
+ "description": "The S3 object key",
500
608
  "schema": {
501
609
  "type": "string"
502
- }
610
+ },
611
+ "example": "123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf"
503
612
  },
504
613
  {
505
614
  "name": "s3_bucket",
506
615
  "in": "query",
507
616
  "required": true,
617
+ "description": "The S3 bucket name",
508
618
  "schema": {
509
619
  "type": "string"
510
- }
620
+ },
621
+ "example": "epilot-prod-user-content"
511
622
  },
512
623
  {
513
624
  "name": "attachment",
514
625
  "in": "query",
515
- "description": "Controls the Content-Disposition header to control browser behaviour. Set to true to trigger download.",
626
+ "description": "Controls the Content-Disposition header. Set to `true` to trigger browser download dialog, `false` to display inline.",
516
627
  "schema": {
517
628
  "type": "boolean",
518
629
  "default": true
@@ -521,7 +632,7 @@
521
632
  ],
522
633
  "responses": {
523
634
  "200": {
524
- "description": "Generated thumbnail image",
635
+ "description": "Pre-signed download URL",
525
636
  "content": {
526
637
  "application/json": {
527
638
  "schema": {
@@ -530,12 +641,25 @@
530
641
  "download_url": {
531
642
  "type": "string",
532
643
  "format": "uri",
644
+ "description": "Pre-signed S3 URL valid for downloading the file",
533
645
  "example": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/temp/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf?AWSParams=123"
534
646
  }
535
647
  }
536
648
  }
537
649
  }
538
650
  }
651
+ },
652
+ "400": {
653
+ "$ref": "#/components/responses/BadRequestError"
654
+ },
655
+ "401": {
656
+ "$ref": "#/components/responses/UnauthorizedError"
657
+ },
658
+ "404": {
659
+ "$ref": "#/components/responses/NotFoundError"
660
+ },
661
+ "500": {
662
+ "$ref": "#/components/responses/InternalServerError"
539
663
  }
540
664
  }
541
665
  }
@@ -544,7 +668,7 @@
544
668
  "post": {
545
669
  "operationId": "downloadFiles",
546
670
  "summary": "downloadFiles",
547
- "description": "Bulk generate pre-signed download S3 urls for multiple files",
671
+ "description": "Bulk generate pre-signed download URLs for multiple files in a single request.\n\nThis is more efficient than calling `downloadFile` multiple times when you need to download several files.\n",
548
672
  "tags": [
549
673
  "File"
550
674
  ],
@@ -553,13 +677,27 @@
553
677
  "application/json": {
554
678
  "schema": {
555
679
  "$ref": "#/components/schemas/DownloadFilesPayload"
680
+ },
681
+ "examples": {
682
+ "Download multiple files": {
683
+ "value": [
684
+ {
685
+ "id": "ef7d985c-2385-44f4-9c71-ae06a52264f8",
686
+ "version": 0
687
+ },
688
+ {
689
+ "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
690
+ "version": 0
691
+ }
692
+ ]
693
+ }
556
694
  }
557
695
  }
558
696
  }
559
697
  },
560
698
  "responses": {
561
699
  "200": {
562
- "description": "Generated download urls",
700
+ "description": "Generated download URLs for each requested file",
563
701
  "content": {
564
702
  "application/json": {
565
703
  "schema": {
@@ -570,17 +708,38 @@
570
708
  "download_url": {
571
709
  "type": "string",
572
710
  "format": "uri",
711
+ "description": "Pre-signed S3 URL for downloading the file",
573
712
  "example": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/temp/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf?AWSParams=123"
574
713
  },
575
714
  "file_entity_id": {
576
715
  "type": "string",
577
- "format": "uuid"
716
+ "format": "uuid",
717
+ "description": "The file entity ID (matches the requested ID)"
578
718
  }
579
719
  }
580
720
  }
581
- }
721
+ },
722
+ "example": [
723
+ {
724
+ "download_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/document.pdf?X-Amz-...",
725
+ "file_entity_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8"
726
+ },
727
+ {
728
+ "download_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/image.png?X-Amz-...",
729
+ "file_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
730
+ }
731
+ ]
582
732
  }
583
733
  }
734
+ },
735
+ "400": {
736
+ "$ref": "#/components/responses/BadRequestError"
737
+ },
738
+ "401": {
739
+ "$ref": "#/components/responses/UnauthorizedError"
740
+ },
741
+ "500": {
742
+ "$ref": "#/components/responses/InternalServerError"
584
743
  }
585
744
  }
586
745
  }
@@ -589,7 +748,7 @@
589
748
  "get": {
590
749
  "operationId": "previewFile",
591
750
  "summary": "previewFile",
592
- "description": "Generate thumbnail preview for a file entity",
751
+ "description": "Generate a thumbnail preview for a file entity.\n\nSupported file types include images (PNG, JPEG, GIF, WebP), PDFs, and common document formats.\nThe preview is returned as an image (PNG or JPEG).\n\n**Tip:** Use with CookieAuth to embed previews directly in `<img>` tags.\n",
593
752
  "tags": [
594
753
  "Preview"
595
754
  ],
@@ -598,6 +757,7 @@
598
757
  "name": "id",
599
758
  "in": "path",
600
759
  "required": true,
760
+ "description": "The UUID of the file entity",
601
761
  "schema": {
602
762
  "$ref": "#/components/schemas/FileEntityId"
603
763
  }
@@ -605,7 +765,7 @@
605
765
  {
606
766
  "name": "version",
607
767
  "in": "query",
608
- "description": "index of file version",
768
+ "description": "Index of the file version to preview (0 = latest)",
609
769
  "schema": {
610
770
  "type": "integer",
611
771
  "default": 0
@@ -614,27 +774,48 @@
614
774
  {
615
775
  "name": "w",
616
776
  "in": "query",
617
- "description": "width",
777
+ "description": "Desired width in pixels (maintains aspect ratio if only width is specified)",
618
778
  "schema": {
619
779
  "type": "integer"
620
- }
780
+ },
781
+ "example": 200
621
782
  },
622
783
  {
623
784
  "name": "h",
624
785
  "in": "query",
625
- "description": "height",
786
+ "description": "Desired height in pixels (maintains aspect ratio if only height is specified)",
626
787
  "schema": {
627
788
  "type": "integer"
628
- }
789
+ },
790
+ "example": 200
629
791
  }
630
792
  ],
631
793
  "responses": {
632
794
  "200": {
633
795
  "description": "Generated thumbnail image",
634
796
  "content": {
635
- "image/png": {},
636
- "image/jpeg": {}
797
+ "image/png": {
798
+ "schema": {
799
+ "type": "string",
800
+ "format": "binary"
801
+ }
802
+ },
803
+ "image/jpeg": {
804
+ "schema": {
805
+ "type": "string",
806
+ "format": "binary"
807
+ }
808
+ }
637
809
  }
810
+ },
811
+ "401": {
812
+ "$ref": "#/components/responses/UnauthorizedError"
813
+ },
814
+ "404": {
815
+ "$ref": "#/components/responses/NotFoundError"
816
+ },
817
+ "500": {
818
+ "$ref": "#/components/responses/InternalServerError"
638
819
  }
639
820
  }
640
821
  }
@@ -643,7 +824,7 @@
643
824
  "post": {
644
825
  "operationId": "previewS3File",
645
826
  "summary": "previewS3File",
646
- "description": "Generate thumbnail preview from an s3 reference for a file entity",
827
+ "description": "Generate a thumbnail preview from an S3 reference.\n\nUse this endpoint when you have the S3 bucket and key but not the file entity ID.\n",
647
828
  "tags": [
648
829
  "Preview"
649
830
  ],
@@ -651,18 +832,20 @@
651
832
  {
652
833
  "name": "w",
653
834
  "in": "query",
654
- "description": "width",
835
+ "description": "Desired width in pixels",
655
836
  "schema": {
656
837
  "type": "integer"
657
- }
838
+ },
839
+ "example": 200
658
840
  },
659
841
  {
660
842
  "name": "h",
661
843
  "in": "query",
662
- "description": "height",
844
+ "description": "Desired height in pixels",
663
845
  "schema": {
664
846
  "type": "integer"
665
- }
847
+ },
848
+ "example": 200
666
849
  }
667
850
  ],
668
851
  "requestBody": {
@@ -670,6 +853,14 @@
670
853
  "application/json": {
671
854
  "schema": {
672
855
  "$ref": "#/components/schemas/S3Ref"
856
+ },
857
+ "examples": {
858
+ "Preview from S3": {
859
+ "value": {
860
+ "bucket": "epilot-prod-user-content",
861
+ "key": "123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/image.png"
862
+ }
863
+ }
673
864
  }
674
865
  }
675
866
  }
@@ -678,16 +869,38 @@
678
869
  "200": {
679
870
  "description": "Generated thumbnail image",
680
871
  "content": {
681
- "image/png": {},
682
- "image/jpeg": {}
872
+ "image/png": {
873
+ "schema": {
874
+ "type": "string",
875
+ "format": "binary"
876
+ }
877
+ },
878
+ "image/jpeg": {
879
+ "schema": {
880
+ "type": "string",
881
+ "format": "binary"
882
+ }
883
+ }
683
884
  }
885
+ },
886
+ "400": {
887
+ "$ref": "#/components/responses/BadRequestError"
888
+ },
889
+ "401": {
890
+ "$ref": "#/components/responses/UnauthorizedError"
891
+ },
892
+ "404": {
893
+ "$ref": "#/components/responses/NotFoundError"
894
+ },
895
+ "500": {
896
+ "$ref": "#/components/responses/InternalServerError"
684
897
  }
685
898
  }
686
899
  },
687
900
  "get": {
688
901
  "operationId": "previewS3FileGet",
689
902
  "summary": "previewS3FileGet",
690
- "description": "Get thumbnail preview from an s3 reference for a file entity",
903
+ "description": "Get a thumbnail preview from an S3 reference using query parameters.\n\nThis GET variant is useful for embedding previews directly in `<img>` tags.\n",
691
904
  "tags": [
692
905
  "Preview"
693
906
  ],
@@ -695,45 +908,71 @@
695
908
  {
696
909
  "name": "key",
697
910
  "in": "query",
698
- "description": "s3 key",
911
+ "description": "The S3 object key",
699
912
  "required": true,
700
913
  "schema": {
701
914
  "type": "string"
702
- }
915
+ },
916
+ "example": "123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/image.png"
703
917
  },
704
918
  {
705
919
  "name": "bucket",
706
920
  "in": "query",
707
- "description": "s3 bucket",
921
+ "description": "The S3 bucket name",
708
922
  "required": true,
709
923
  "schema": {
710
924
  "type": "string"
711
- }
925
+ },
926
+ "example": "epilot-prod-user-content"
712
927
  },
713
928
  {
714
929
  "name": "w",
715
930
  "in": "query",
716
- "description": "width",
931
+ "description": "Desired width in pixels",
717
932
  "schema": {
718
933
  "type": "integer"
719
- }
934
+ },
935
+ "example": 200
720
936
  },
721
937
  {
722
938
  "name": "h",
723
939
  "in": "query",
724
- "description": "height",
940
+ "description": "Desired height in pixels",
725
941
  "schema": {
726
942
  "type": "integer"
727
- }
943
+ },
944
+ "example": 200
728
945
  }
729
946
  ],
730
947
  "responses": {
731
948
  "200": {
732
949
  "description": "Generated thumbnail image",
733
950
  "content": {
734
- "image/png": {},
735
- "image/jpeg": {}
951
+ "image/png": {
952
+ "schema": {
953
+ "type": "string",
954
+ "format": "binary"
955
+ }
956
+ },
957
+ "image/jpeg": {
958
+ "schema": {
959
+ "type": "string",
960
+ "format": "binary"
961
+ }
962
+ }
736
963
  }
964
+ },
965
+ "400": {
966
+ "$ref": "#/components/responses/BadRequestError"
967
+ },
968
+ "401": {
969
+ "$ref": "#/components/responses/UnauthorizedError"
970
+ },
971
+ "404": {
972
+ "$ref": "#/components/responses/NotFoundError"
973
+ },
974
+ "500": {
975
+ "$ref": "#/components/responses/InternalServerError"
737
976
  }
738
977
  }
739
978
  }
@@ -742,7 +981,7 @@
742
981
  "get": {
743
982
  "operationId": "previewPublicFile",
744
983
  "summary": "previewPublicFile",
745
- "description": "Generate thumbnail preview for a public file entity",
984
+ "description": "Generate a thumbnail preview for a public file entity.\n\n**No authentication required.** This endpoint only works for files with `access_control: public-read`.\n",
746
985
  "security": [],
747
986
  "tags": [
748
987
  "Preview"
@@ -752,6 +991,7 @@
752
991
  "name": "id",
753
992
  "in": "path",
754
993
  "required": true,
994
+ "description": "The UUID of the public file entity",
755
995
  "schema": {
756
996
  "$ref": "#/components/schemas/FileEntityId"
757
997
  }
@@ -759,7 +999,7 @@
759
999
  {
760
1000
  "name": "version",
761
1001
  "in": "query",
762
- "description": "index of file version",
1002
+ "description": "Index of the file version to preview (0 = latest)",
763
1003
  "schema": {
764
1004
  "type": "integer",
765
1005
  "default": 0
@@ -768,35 +1008,68 @@
768
1008
  {
769
1009
  "name": "w",
770
1010
  "in": "query",
771
- "description": "width",
1011
+ "description": "Desired width in pixels",
772
1012
  "schema": {
773
1013
  "type": "integer"
774
- }
1014
+ },
1015
+ "example": 200
775
1016
  },
776
1017
  {
777
1018
  "name": "h",
778
1019
  "in": "query",
779
- "description": "height",
1020
+ "description": "Desired height in pixels",
780
1021
  "schema": {
781
1022
  "type": "integer"
782
- }
1023
+ },
1024
+ "example": 200
783
1025
  },
784
1026
  {
785
1027
  "name": "org_id",
786
1028
  "in": "query",
787
- "description": "Org id",
1029
+ "description": "Organization ID that owns the file",
788
1030
  "schema": {
789
1031
  "type": "string"
790
- }
1032
+ },
1033
+ "example": "123"
791
1034
  }
792
1035
  ],
793
1036
  "responses": {
794
1037
  "200": {
795
1038
  "description": "Generated thumbnail image for a public file",
796
1039
  "content": {
797
- "image/png": {},
798
- "image/jpeg": {}
1040
+ "image/png": {
1041
+ "schema": {
1042
+ "type": "string",
1043
+ "format": "binary"
1044
+ }
1045
+ },
1046
+ "image/jpeg": {
1047
+ "schema": {
1048
+ "type": "string",
1049
+ "format": "binary"
1050
+ }
1051
+ }
799
1052
  }
1053
+ },
1054
+ "403": {
1055
+ "description": "File is not public",
1056
+ "content": {
1057
+ "application/json": {
1058
+ "schema": {
1059
+ "$ref": "#/components/schemas/ErrorObject"
1060
+ },
1061
+ "example": {
1062
+ "status": 403,
1063
+ "error": "File is not publicly accessible"
1064
+ }
1065
+ }
1066
+ }
1067
+ },
1068
+ "404": {
1069
+ "$ref": "#/components/responses/NotFoundError"
1070
+ },
1071
+ "500": {
1072
+ "$ref": "#/components/responses/InternalServerError"
800
1073
  }
801
1074
  }
802
1075
  }
@@ -805,26 +1078,38 @@
805
1078
  "get": {
806
1079
  "operationId": "getSession",
807
1080
  "summary": "getSession",
808
- "description": "Start a browser session by setting passed Authorization token in a server side cookie.\n\nAllows using preview urls directly in img src for private files using cookie authentication.\n",
1081
+ "description": "Start a browser session by converting a Bearer token into a server-side cookie.\n\n**Use case:** After calling this endpoint, you can use preview URLs directly in `<img>` tags\nwithout needing to set the Authorization header manually.\n\n**Example flow:**\n1. Call this endpoint with your Bearer token: `GET /v1/files/session` with `Authorization: Bearer <token>`\n2. The server sets an HTTP-only cookie named `token`\n3. Use preview URLs directly: `<img src=\"https://file.sls.epilot.io/v1/files/{id}/preview\" />`\n",
809
1082
  "tags": [
810
1083
  "Session"
811
1084
  ],
812
1085
  "responses": {
813
1086
  "200": {
814
- "description": "Session started successfully"
1087
+ "description": "Session started successfully. A session cookie has been set.",
1088
+ "headers": {
1089
+ "Set-Cookie": {
1090
+ "description": "HTTP-only session cookie containing the authentication token",
1091
+ "schema": {
1092
+ "type": "string",
1093
+ "example": "token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...; HttpOnly; Secure; Path=/"
1094
+ }
1095
+ }
1096
+ }
1097
+ },
1098
+ "401": {
1099
+ "$ref": "#/components/responses/UnauthorizedError"
815
1100
  }
816
1101
  }
817
1102
  },
818
1103
  "delete": {
819
1104
  "operationId": "deleteSession",
820
1105
  "summary": "deleteSession",
821
- "description": "End browser session by deleting token cookie",
1106
+ "description": "End a browser session by deleting the token cookie.\n\nCall this endpoint to log out and clear the session cookie.\n",
822
1107
  "tags": [
823
1108
  "Session"
824
1109
  ],
825
1110
  "responses": {
826
1111
  "200": {
827
- "description": "Session deleted successfully"
1112
+ "description": "Session deleted successfully. The session cookie has been cleared."
828
1113
  }
829
1114
  }
830
1115
  }
@@ -833,7 +1118,7 @@
833
1118
  "post": {
834
1119
  "operationId": "generatePublicLink",
835
1120
  "summary": "generatePublicLink",
836
- "description": "Generates a public link to access a private file\n",
1121
+ "description": "Generate a public link to share a private file externally.\n\nThe generated link:\n- Is permanent until explicitly revoked\n- Includes the filename for user-friendly URLs\n- Does not require authentication to access\n- Redirects to a signed download URL when accessed\n\n**Use case:** Share invoices, contracts, or documents with external parties who don't have epilot accounts.\n",
837
1122
  "tags": [
838
1123
  "Public Links"
839
1124
  ],
@@ -842,6 +1127,7 @@
842
1127
  "name": "id",
843
1128
  "in": "path",
844
1129
  "required": true,
1130
+ "description": "The UUID of the file entity to share",
845
1131
  "schema": {
846
1132
  "$ref": "#/components/schemas/FileEntityId"
847
1133
  }
@@ -849,33 +1135,46 @@
849
1135
  ],
850
1136
  "responses": {
851
1137
  "201": {
852
- "description": "Returns the public link which can be used to access the file later",
1138
+ "description": "Public link generated successfully",
853
1139
  "content": {
854
1140
  "application/json": {
855
1141
  "schema": {
856
1142
  "type": "string",
857
- "example": "https://file.sls.epilot.io/v1/files/public/links/3ef5c6d9-818d-45e6-8efb-b1de59079a1c/invoice-2023-12.pdf"
858
- }
1143
+ "description": "The public URL that can be shared externally"
1144
+ },
1145
+ "example": "https://file.sls.epilot.io/v1/files/public/links/3ef5c6d9-818d-45e6-8efb-b1de59079a1c/invoice-2023-12.pdf"
859
1146
  }
860
1147
  }
1148
+ },
1149
+ "401": {
1150
+ "$ref": "#/components/responses/UnauthorizedError"
1151
+ },
1152
+ "403": {
1153
+ "$ref": "#/components/responses/ForbiddenError"
1154
+ },
1155
+ "404": {
1156
+ "$ref": "#/components/responses/NotFoundError"
1157
+ },
1158
+ "500": {
1159
+ "$ref": "#/components/responses/InternalServerError"
861
1160
  }
862
1161
  }
863
1162
  },
864
1163
  "get": {
865
1164
  "operationId": "listPublicLinksForFile",
866
1165
  "summary": "listPublicLinksForFile",
867
- "description": "Not yet implemented; This API would fetch all the public links that are previously generated for a file",
1166
+ "description": "**Not yet implemented.**\n\nThis endpoint will fetch all public links previously generated for a file.\n",
868
1167
  "x-not-implemented": true,
869
1168
  "parameters": [
870
1169
  {
871
1170
  "name": "id",
872
1171
  "in": "path",
873
1172
  "required": true,
1173
+ "description": "The UUID of the file entity",
874
1174
  "schema": {
875
- "type": "string",
876
- "description": "ID of the file entity",
877
- "example": "13d22918-36bd-4227-9ad4-2cb978788c8d"
878
- }
1175
+ "type": "string"
1176
+ },
1177
+ "example": "13d22918-36bd-4227-9ad4-2cb978788c8d"
879
1178
  }
880
1179
  ],
881
1180
  "tags": [
@@ -883,7 +1182,7 @@
883
1182
  ],
884
1183
  "responses": {
885
1184
  "200": {
886
- "description": "Public links of a file retrieved successfully",
1185
+ "description": "Public links retrieved successfully",
887
1186
  "content": {
888
1187
  "application/json": {
889
1188
  "schema": {
@@ -896,6 +1195,29 @@
896
1195
  }
897
1196
  }
898
1197
  }
1198
+ },
1199
+ "example": {
1200
+ "results": [
1201
+ {
1202
+ "id": "3ef5c6d9-818d-45e6-8efb-b1de59079a1c",
1203
+ "link": "https://file.sls.epilot.io/v1/files/public/links/3ef5c6d9-818d-45e6-8efb-b1de59079a1c/invoice.pdf",
1204
+ "last_accessed_at": "2024-01-15T10:30:00Z"
1205
+ }
1206
+ ]
1207
+ }
1208
+ }
1209
+ }
1210
+ },
1211
+ "501": {
1212
+ "description": "Not implemented",
1213
+ "content": {
1214
+ "application/json": {
1215
+ "schema": {
1216
+ "$ref": "#/components/schemas/ErrorObject"
1217
+ },
1218
+ "example": {
1219
+ "status": 501,
1220
+ "error": "Not Implemented"
899
1221
  }
900
1222
  }
901
1223
  }
@@ -911,41 +1233,69 @@
911
1233
  "tags": [
912
1234
  "Public Links"
913
1235
  ],
914
- "description": "Redirects to a accessible signed url for the respective file associated to the public link",
1236
+ "description": "Access a file via its public link.\n\n**No authentication required.** This endpoint redirects to a signed S3 URL for downloading the file.\n\nThe filename in the URL is for user-friendliness and SEO; the actual file is identified by the link ID.\n",
915
1237
  "parameters": [
916
1238
  {
917
1239
  "name": "id",
918
1240
  "in": "path",
919
1241
  "required": true,
1242
+ "description": "The UUID of the public link (not the file entity ID)",
920
1243
  "schema": {
921
- "type": "string",
922
- "description": "Id of the publicly generated link",
923
- "example": "13d22918-36bd-4227-9ad4-2cb978788c8d"
924
- }
1244
+ "type": "string"
1245
+ },
1246
+ "example": "13d22918-36bd-4227-9ad4-2cb978788c8d"
925
1247
  },
926
1248
  {
927
1249
  "name": "filename",
928
1250
  "in": "path",
929
1251
  "required": true,
1252
+ "description": "The filename (for user-friendly URLs)",
930
1253
  "schema": {
931
- "type": "string",
932
- "description": "Name of the file",
933
- "example": "invoice-2023-12.pdf"
934
- }
1254
+ "type": "string"
1255
+ },
1256
+ "example": "invoice-2023-12.pdf"
935
1257
  },
936
1258
  {
937
1259
  "name": "hash",
938
1260
  "in": "query",
939
1261
  "required": false,
1262
+ "description": "Optional cache-busting hash to force re-download",
940
1263
  "schema": {
941
- "type": "string",
942
- "description": "An optional cache-busting hash for the file"
943
- }
1264
+ "type": "string"
1265
+ },
1266
+ "example": "abc123"
944
1267
  }
945
1268
  ],
946
1269
  "responses": {
947
1270
  "302": {
948
- "description": "Redirect to signed URL where the caller can access the file"
1271
+ "description": "Redirect to a signed S3 URL for downloading the file",
1272
+ "headers": {
1273
+ "Location": {
1274
+ "description": "The signed S3 URL to download the file",
1275
+ "schema": {
1276
+ "type": "string",
1277
+ "format": "uri"
1278
+ },
1279
+ "example": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/document.pdf?X-Amz-..."
1280
+ }
1281
+ }
1282
+ },
1283
+ "404": {
1284
+ "description": "Public link not found or has been revoked",
1285
+ "content": {
1286
+ "application/json": {
1287
+ "schema": {
1288
+ "$ref": "#/components/schemas/ErrorObject"
1289
+ },
1290
+ "example": {
1291
+ "status": 404,
1292
+ "error": "Public link not found"
1293
+ }
1294
+ }
1295
+ }
1296
+ },
1297
+ "500": {
1298
+ "$ref": "#/components/responses/InternalServerError"
949
1299
  }
950
1300
  }
951
1301
  }
@@ -954,18 +1304,18 @@
954
1304
  "delete": {
955
1305
  "operationId": "revokePublicLink",
956
1306
  "summary": "revokePublicLink",
957
- "description": "Not yet implemented; This operation would revoke a given public link by ID",
1307
+ "description": "**Not yet implemented.**\n\nThis endpoint will revoke a public link, making the file inaccessible via that link.\n",
958
1308
  "x-not-implemented": true,
959
1309
  "parameters": [
960
1310
  {
961
1311
  "name": "id",
962
1312
  "in": "path",
963
1313
  "required": true,
1314
+ "description": "The UUID of the public link to revoke",
964
1315
  "schema": {
965
- "type": "string",
966
- "description": "Id of the publicly generated link",
967
- "example": "13d22918-36bd-4227-9ad4-2cb978788c8d"
968
- }
1316
+ "type": "string"
1317
+ },
1318
+ "example": "13d22918-36bd-4227-9ad4-2cb978788c8d"
969
1319
  }
970
1320
  ],
971
1321
  "tags": [
@@ -973,12 +1323,18 @@
973
1323
  ],
974
1324
  "responses": {
975
1325
  "204": {
976
- "description": "Revokes a public link successfully.",
1326
+ "description": "Public link revoked successfully"
1327
+ },
1328
+ "501": {
1329
+ "description": "Not implemented",
977
1330
  "content": {
978
1331
  "application/json": {
979
1332
  "schema": {
980
- "type": "string",
981
- "example": "https://file.sls.epilot.io/v1/files/public/links/3ef5c6d9-818d-45e6-8efb-b1de59079a1c"
1333
+ "$ref": "#/components/schemas/ErrorObject"
1334
+ },
1335
+ "example": {
1336
+ "status": 501,
1337
+ "error": "Not Implemented"
982
1338
  }
983
1339
  }
984
1340
  }
@@ -990,7 +1346,7 @@
990
1346
  "post": {
991
1347
  "operationId": "verifyCustomDownloadUrl",
992
1348
  "summary": "verifyCustomDownloadUrl",
993
- "description": "Verify a pre-signed custom download url for a file",
1349
+ "description": "Verify that a custom download URL is valid and has not expired.\n\nUse this endpoint to validate custom download URLs before redirecting users.\nCustom download URLs include a signature and expiration time for security.\n",
994
1350
  "tags": [
995
1351
  "File"
996
1352
  ],
@@ -999,25 +1355,54 @@
999
1355
  "application/json": {
1000
1356
  "schema": {
1001
1357
  "$ref": "#/components/schemas/VerifyCustomDownloadUrlPayload"
1358
+ },
1359
+ "examples": {
1360
+ "Verify URL": {
1361
+ "value": {
1362
+ "custom_download_url": "https://some-api-url.com?file_id=123&expires_at=1699273500029&signature=abcdefg"
1363
+ }
1364
+ }
1002
1365
  }
1003
1366
  }
1004
1367
  }
1005
1368
  },
1006
1369
  "responses": {
1007
1370
  "200": {
1008
- "description": "Download Url matches signature and has not expired",
1371
+ "description": "Verification result",
1009
1372
  "content": {
1010
1373
  "application/json": {
1011
1374
  "schema": {
1012
1375
  "type": "object",
1013
1376
  "properties": {
1014
1377
  "valid": {
1015
- "type": "boolean"
1378
+ "type": "boolean",
1379
+ "description": "Whether the URL is valid and not expired"
1380
+ }
1381
+ }
1382
+ },
1383
+ "examples": {
1384
+ "Valid URL": {
1385
+ "value": {
1386
+ "valid": true
1387
+ }
1388
+ },
1389
+ "Invalid URL": {
1390
+ "value": {
1391
+ "valid": false
1016
1392
  }
1017
1393
  }
1018
1394
  }
1019
1395
  }
1020
1396
  }
1397
+ },
1398
+ "400": {
1399
+ "$ref": "#/components/responses/BadRequestError"
1400
+ },
1401
+ "401": {
1402
+ "$ref": "#/components/responses/UnauthorizedError"
1403
+ },
1404
+ "500": {
1405
+ "$ref": "#/components/responses/InternalServerError"
1021
1406
  }
1022
1407
  }
1023
1408
  }
@@ -1027,7 +1412,7 @@
1027
1412
  "operationId": "uploadFilePublic",
1028
1413
  "summary": "uploadFilePublic",
1029
1414
  "security": [],
1030
- "description": "Create pre-signed S3 URL to upload a file to keep temporarily (one week).\n\nUse the saveFileV2 operation to store file file permanently.\n",
1415
+ "description": "Create a pre-signed S3 URL for uploading a file without authentication.\n\n**No authentication required.** This endpoint is intended for public-facing forms and journeys\nwhere end-users need to upload files without logging in.\n\nThe uploaded file is stored temporarily (one week). Use `saveFileV2` with proper authentication\nto store the file permanently.\n\n**Security note:** Files uploaded via this endpoint are temporary and require authenticated\naccess to be saved permanently.\n",
1031
1416
  "tags": [
1032
1417
  "File"
1033
1418
  ],
@@ -1038,7 +1423,7 @@
1038
1423
  "$ref": "#/components/schemas/UploadFilePayload"
1039
1424
  },
1040
1425
  "examples": {
1041
- "Upload an image file": {
1426
+ "Upload an image": {
1042
1427
  "description": "Upload an image file",
1043
1428
  "value": {
1044
1429
  "filename": "image.png",
@@ -1046,7 +1431,7 @@
1046
1431
  }
1047
1432
  },
1048
1433
  "Upload a document": {
1049
- "description": "Upload an image file",
1434
+ "description": "Upload a PDF document",
1050
1435
  "value": {
1051
1436
  "filename": "document.pdf",
1052
1437
  "mime_type": "application/pdf"
@@ -1058,7 +1443,7 @@
1058
1443
  },
1059
1444
  "responses": {
1060
1445
  "201": {
1061
- "description": "Pre-signed URL for POST / PUT upload",
1446
+ "description": "Pre-signed URL for uploading the file",
1062
1447
  "content": {
1063
1448
  "application/json": {
1064
1449
  "schema": {
@@ -1069,6 +1454,9 @@
1069
1454
  {
1070
1455
  "$ref": "#/components/schemas/S3Ref"
1071
1456
  },
1457
+ {
1458
+ "description": "S3 reference to use when saving the file permanently"
1459
+ },
1072
1460
  {
1073
1461
  "example": {
1074
1462
  "bucket": "epilot-prod-user-content",
@@ -1080,16 +1468,24 @@
1080
1468
  "upload_url": {
1081
1469
  "type": "string",
1082
1470
  "format": "url",
1471
+ "description": "Pre-signed URL for uploading the file via PUT request",
1083
1472
  "example": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/temp/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf?AWSParams=123"
1084
1473
  },
1085
1474
  "error": {
1086
1475
  "type": "string",
1476
+ "description": "Error message if the upload preparation failed",
1087
1477
  "example": "File entity not found"
1088
1478
  }
1089
1479
  }
1090
1480
  }
1091
1481
  }
1092
1482
  }
1483
+ },
1484
+ "400": {
1485
+ "$ref": "#/components/responses/BadRequestError"
1486
+ },
1487
+ "500": {
1488
+ "$ref": "#/components/responses/InternalServerError"
1093
1489
  }
1094
1490
  }
1095
1491
  }
@@ -1098,7 +1494,7 @@
1098
1494
  "get": {
1099
1495
  "operationId": "getUserSchemaFileCollections",
1100
1496
  "summary": "getUserSchemaFileCollections",
1101
- "description": "Gets a list of file collections for the current user and schema",
1497
+ "description": "Get all file collections for the current user within a specific schema.\n\nCollections help organize files into logical groups (e.g., \"Contracts\", \"Invoices\").\nUser collections are private to the creating user.\n",
1102
1498
  "tags": [
1103
1499
  "File Collections"
1104
1500
  ],
@@ -1107,11 +1503,11 @@
1107
1503
  "name": "slug",
1108
1504
  "in": "path",
1109
1505
  "required": true,
1110
- "description": "The schema slug (e.g., order, opportunity)",
1506
+ "description": "The entity schema slug (e.g., order, opportunity, contact)",
1111
1507
  "schema": {
1112
- "type": "string",
1113
- "example": "opportunity"
1114
- }
1508
+ "type": "string"
1509
+ },
1510
+ "example": "opportunity"
1115
1511
  }
1116
1512
  ],
1117
1513
  "responses": {
@@ -1124,16 +1520,34 @@
1124
1520
  "items": {
1125
1521
  "$ref": "#/components/schemas/FileCollectionItem"
1126
1522
  }
1127
- }
1523
+ },
1524
+ "example": [
1525
+ {
1526
+ "slug": "_system_files_collection_3fa85f64-5717-4562-b3fc-2c963f66afa6_10234:documents",
1527
+ "name": "Documents",
1528
+ "id": "ef7d985c-2385-44f4-9c71-ae06a52264f8",
1529
+ "parents": [],
1530
+ "starred": false,
1531
+ "order": 0,
1532
+ "created_at": "2024-01-01T12:00:00Z",
1533
+ "updated_at": "2024-01-02T12:00:00Z"
1534
+ }
1535
+ ]
1128
1536
  }
1129
1537
  }
1538
+ },
1539
+ "401": {
1540
+ "$ref": "#/components/responses/UnauthorizedError"
1541
+ },
1542
+ "500": {
1543
+ "$ref": "#/components/responses/InternalServerError"
1130
1544
  }
1131
1545
  }
1132
1546
  },
1133
1547
  "post": {
1134
1548
  "operationId": "createUserSchemaFileCollection",
1135
1549
  "summary": "createUserSchemaFileCollection",
1136
- "description": "Creates a new file collection for the current user and schema",
1550
+ "description": "Create a new file collection for the current user within a specific schema.\n\nThe collection will be private to the creating user and associated with the specified schema.\n",
1137
1551
  "tags": [
1138
1552
  "File Collections"
1139
1553
  ],
@@ -1142,11 +1556,11 @@
1142
1556
  "name": "slug",
1143
1557
  "in": "path",
1144
1558
  "required": true,
1145
- "description": "The schema slug (e.g., order, opportunity)",
1559
+ "description": "The entity schema slug (e.g., order, opportunity, contact)",
1146
1560
  "schema": {
1147
- "type": "string",
1148
- "example": "opportunity"
1149
- }
1561
+ "type": "string"
1562
+ },
1563
+ "example": "opportunity"
1150
1564
  }
1151
1565
  ],
1152
1566
  "requestBody": {
@@ -1155,6 +1569,22 @@
1155
1569
  "application/json": {
1156
1570
  "schema": {
1157
1571
  "$ref": "#/components/schemas/FileCollectionCreateRequest"
1572
+ },
1573
+ "examples": {
1574
+ "Create collection": {
1575
+ "value": {
1576
+ "name": "Contracts",
1577
+ "starred": false
1578
+ }
1579
+ },
1580
+ "Create nested collection": {
1581
+ "value": {
1582
+ "name": "2024 Contracts",
1583
+ "parents": [
1584
+ "_system_files_collection_3fa85f64-5717-4562-b3fc-2c963f66afa6_10234:contracts"
1585
+ ]
1586
+ }
1587
+ }
1158
1588
  }
1159
1589
  }
1160
1590
  }
@@ -1169,6 +1599,15 @@
1169
1599
  }
1170
1600
  }
1171
1601
  }
1602
+ },
1603
+ "400": {
1604
+ "$ref": "#/components/responses/BadRequestError"
1605
+ },
1606
+ "401": {
1607
+ "$ref": "#/components/responses/UnauthorizedError"
1608
+ },
1609
+ "500": {
1610
+ "$ref": "#/components/responses/InternalServerError"
1172
1611
  }
1173
1612
  }
1174
1613
  }
@@ -1177,7 +1616,7 @@
1177
1616
  "put": {
1178
1617
  "operationId": "updateUserSchemaFileCollection",
1179
1618
  "summary": "updateUserSchemaFileCollection",
1180
- "description": "Updates a file collection for the current user and schema",
1619
+ "description": "Update an existing file collection.\n\nYou can update the name, parent relationships, starred status, and enabled locations/purposes.\n",
1181
1620
  "tags": [
1182
1621
  "File Collections"
1183
1622
  ],
@@ -1186,21 +1625,21 @@
1186
1625
  "name": "slug",
1187
1626
  "in": "path",
1188
1627
  "required": true,
1189
- "description": "The schema slug (e.g., order, opportunity)",
1628
+ "description": "The entity schema slug (e.g., order, opportunity)",
1190
1629
  "schema": {
1191
- "type": "string",
1192
- "example": "opportunity"
1193
- }
1630
+ "type": "string"
1631
+ },
1632
+ "example": "opportunity"
1194
1633
  },
1195
1634
  {
1196
1635
  "name": "collectionSlug",
1197
1636
  "in": "path",
1198
1637
  "required": true,
1199
- "description": "The slug identifier for the collection",
1638
+ "description": "The collection slug identifier",
1200
1639
  "schema": {
1201
- "type": "string",
1202
- "example": "documents"
1203
- }
1640
+ "type": "string"
1641
+ },
1642
+ "example": "documents"
1204
1643
  }
1205
1644
  ],
1206
1645
  "requestBody": {
@@ -1209,6 +1648,18 @@
1209
1648
  "application/json": {
1210
1649
  "schema": {
1211
1650
  "$ref": "#/components/schemas/FileCollectionAttributes"
1651
+ },
1652
+ "examples": {
1653
+ "Rename collection": {
1654
+ "value": {
1655
+ "name": "Important Documents"
1656
+ }
1657
+ },
1658
+ "Star collection": {
1659
+ "value": {
1660
+ "starred": true
1661
+ }
1662
+ }
1212
1663
  }
1213
1664
  }
1214
1665
  }
@@ -1224,15 +1675,24 @@
1224
1675
  }
1225
1676
  }
1226
1677
  },
1678
+ "400": {
1679
+ "$ref": "#/components/responses/BadRequestError"
1680
+ },
1681
+ "401": {
1682
+ "$ref": "#/components/responses/UnauthorizedError"
1683
+ },
1227
1684
  "404": {
1228
1685
  "$ref": "#/components/responses/NotFoundError"
1686
+ },
1687
+ "500": {
1688
+ "$ref": "#/components/responses/InternalServerError"
1229
1689
  }
1230
1690
  }
1231
1691
  },
1232
1692
  "delete": {
1233
1693
  "operationId": "deleteUserSchemaFileCollection",
1234
1694
  "summary": "deleteUserSchemaFileCollection",
1235
- "description": "Deletes a file collection for the current user and schema",
1695
+ "description": "Delete a file collection.\n\n**Note:** Deleting a collection does not delete the files within it.\nFiles will remain but will no longer be associated with this collection.\n",
1236
1696
  "tags": [
1237
1697
  "File Collections"
1238
1698
  ],
@@ -1241,29 +1701,35 @@
1241
1701
  "name": "slug",
1242
1702
  "in": "path",
1243
1703
  "required": true,
1244
- "description": "The schema slug (e.g., order, opportunity)",
1704
+ "description": "The entity schema slug (e.g., order, opportunity)",
1245
1705
  "schema": {
1246
- "type": "string",
1247
- "example": "opportunity"
1248
- }
1706
+ "type": "string"
1707
+ },
1708
+ "example": "opportunity"
1249
1709
  },
1250
1710
  {
1251
1711
  "name": "collectionSlug",
1252
1712
  "in": "path",
1253
1713
  "required": true,
1254
- "description": "The slug identifier for the collection",
1714
+ "description": "The collection slug identifier",
1255
1715
  "schema": {
1256
- "type": "string",
1257
- "example": "documents"
1258
- }
1716
+ "type": "string"
1717
+ },
1718
+ "example": "documents"
1259
1719
  }
1260
1720
  ],
1261
1721
  "responses": {
1262
1722
  "200": {
1263
1723
  "description": "File collection deleted successfully"
1264
1724
  },
1725
+ "401": {
1726
+ "$ref": "#/components/responses/UnauthorizedError"
1727
+ },
1265
1728
  "404": {
1266
1729
  "$ref": "#/components/responses/NotFoundError"
1730
+ },
1731
+ "500": {
1732
+ "$ref": "#/components/responses/InternalServerError"
1267
1733
  }
1268
1734
  }
1269
1735
  }
@@ -1272,7 +1738,7 @@
1272
1738
  "get": {
1273
1739
  "operationId": "getFilesInCollection",
1274
1740
  "summary": "getFilesInCollection",
1275
- "description": "Gets all files within a specific collection for an entity (uses schema-based taxonomy derived from entity)",
1741
+ "description": "Get all files within a specific collection for an entity.\n\nThe schema is automatically derived from the entity. This endpoint requires\nview permission on the parent entity to access its files.\n",
1276
1742
  "tags": [
1277
1743
  "File Collections"
1278
1744
  ],
@@ -1284,11 +1750,11 @@
1284
1750
  "name": "collectionSlug",
1285
1751
  "in": "path",
1286
1752
  "required": true,
1287
- "description": "The slug identifier for the collection",
1753
+ "description": "The collection slug identifier",
1288
1754
  "schema": {
1289
- "type": "string",
1290
- "example": "documents"
1291
- }
1755
+ "type": "string"
1756
+ },
1757
+ "example": "documents"
1292
1758
  }
1293
1759
  ],
1294
1760
  "responses": {
@@ -1305,18 +1771,19 @@
1305
1771
  }
1306
1772
  }
1307
1773
  },
1774
+ "401": {
1775
+ "$ref": "#/components/responses/UnauthorizedError"
1776
+ },
1308
1777
  "403": {
1309
- "description": "User must have permission to view this entity to access its files",
1778
+ "description": "Insufficient permissions to view the entity's files",
1310
1779
  "content": {
1311
1780
  "application/json": {
1312
1781
  "schema": {
1313
- "type": "object",
1314
- "properties": {
1315
- "error": {
1316
- "type": "string",
1317
- "example": "User must have permission to view this entity to access its files"
1318
- }
1319
- }
1782
+ "$ref": "#/components/schemas/ErrorObject"
1783
+ },
1784
+ "example": {
1785
+ "status": 403,
1786
+ "error": "User must have permission to view this entity to access its files"
1320
1787
  }
1321
1788
  }
1322
1789
  }
@@ -1326,16 +1793,17 @@
1326
1793
  "content": {
1327
1794
  "application/json": {
1328
1795
  "schema": {
1329
- "type": "object",
1330
- "properties": {
1331
- "error": {
1332
- "type": "string",
1333
- "example": "Entity not found"
1334
- }
1335
- }
1796
+ "$ref": "#/components/schemas/ErrorObject"
1797
+ },
1798
+ "example": {
1799
+ "status": 404,
1800
+ "error": "Entity not found"
1336
1801
  }
1337
1802
  }
1338
1803
  }
1804
+ },
1805
+ "500": {
1806
+ "$ref": "#/components/responses/InternalServerError"
1339
1807
  }
1340
1808
  }
1341
1809
  }
@@ -1344,7 +1812,7 @@
1344
1812
  "get": {
1345
1813
  "operationId": "getGlobalFileCollections",
1346
1814
  "summary": "getGlobalFileCollections",
1347
- "description": "Gets all global file collections for a specific schema",
1815
+ "description": "Get all global file collections for a specific schema.\n\nGlobal collections are shared across all users in the organization for the specified schema.\nUnlike user collections, these are visible to everyone with access to entities of that schema.\n",
1348
1816
  "tags": [
1349
1817
  "File Collections"
1350
1818
  ],
@@ -1353,11 +1821,11 @@
1353
1821
  "name": "schemaSlug",
1354
1822
  "in": "path",
1355
1823
  "required": true,
1356
- "description": "The schema slug (e.g., order, opportunity)",
1824
+ "description": "The entity schema slug (e.g., order, opportunity, contact)",
1357
1825
  "schema": {
1358
- "type": "string",
1359
- "example": "order"
1360
- }
1826
+ "type": "string"
1827
+ },
1828
+ "example": "order"
1361
1829
  }
1362
1830
  ],
1363
1831
  "responses": {
@@ -1370,9 +1838,27 @@
1370
1838
  "items": {
1371
1839
  "$ref": "#/components/schemas/FileCollectionItem"
1372
1840
  }
1373
- }
1841
+ },
1842
+ "example": [
1843
+ {
1844
+ "slug": "_system_files_collection_schema_order:templates",
1845
+ "name": "Templates",
1846
+ "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
1847
+ "parents": [],
1848
+ "starred": false,
1849
+ "order": 0,
1850
+ "created_at": "2024-01-01T12:00:00Z",
1851
+ "updated_at": "2024-01-01T12:00:00Z"
1852
+ }
1853
+ ]
1374
1854
  }
1375
1855
  }
1856
+ },
1857
+ "401": {
1858
+ "$ref": "#/components/responses/UnauthorizedError"
1859
+ },
1860
+ "500": {
1861
+ "$ref": "#/components/responses/InternalServerError"
1376
1862
  }
1377
1863
  }
1378
1864
  }
@@ -1383,14 +1869,14 @@
1383
1869
  "EpilotAuth": {
1384
1870
  "type": "http",
1385
1871
  "scheme": "bearer",
1386
- "description": "Authorization header with epilot OAuth2 bearer token",
1387
- "bearerFormat": "JWT"
1872
+ "bearerFormat": "JWT",
1873
+ "description": "Bearer token authentication using epilot OAuth2 JWT tokens.\n\n**When to use:** Server-to-server integrations, API clients, and programmatic access.\n\n**How to obtain a token:**\n1. Use the epilot Auth API to authenticate\n2. Include the token in the `Authorization` header: `Authorization: Bearer <token>`\n\n**Example:**\n```\nAuthorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\n```\n\n**Token contents:** The JWT contains user identity, organization ID, and permissions.\n"
1388
1874
  },
1389
1875
  "CookieAuth": {
1390
1876
  "type": "apiKey",
1391
1877
  "in": "cookie",
1392
1878
  "name": "token",
1393
- "description": "Cookie with epilot OAuth2 token"
1879
+ "description": "Cookie-based session authentication for browser applications.\n\n**When to use:** Browser-based applications that need to:\n- Embed file previews directly in `<img>` tags\n- Download files without JavaScript token handling\n- Access files from HTML elements that cannot set custom headers\n\n**How to establish a session:**\n1. Obtain a Bearer token via EpilotAuth\n2. Call `GET /v1/files/session` with the Bearer token\n3. The server sets an HTTP-only cookie named `token`\n4. Subsequent requests automatically include the cookie\n\n**Security note:** The cookie is HTTP-only and secure, protecting against XSS attacks.\n"
1394
1880
  }
1395
1881
  },
1396
1882
  "schemas": {
@@ -2024,8 +2510,8 @@
2024
2510
  "type": "string"
2025
2511
  },
2026
2512
  "example": [
2027
- "purpose:9eefcb98-93cf-4c5b-a040-f1d26d57c177",
2028
- "purpose:5c544c09-a691-43ed-a7fa-0a8b44b5b161"
2513
+ "9eefcb98-93cf-4c5b-a040-f1d26d57c177",
2514
+ "5c544c09-a691-43ed-a7fa-0a8b44b5b161"
2029
2515
  ]
2030
2516
  },
2031
2517
  "created_at": {
@@ -2153,9 +2639,79 @@
2153
2639
  "type": "boolean",
2154
2640
  "default": true
2155
2641
  }
2642
+ },
2643
+ "VersionOnlyQueryParam": {
2644
+ "name": "version_only",
2645
+ "in": "query",
2646
+ "description": "When true, only adds a new file version and updates the entity's\ns3ref to point to the new version, without overwriting the entity's\nexisting top-level metadata. The entity's filename, type, and other\nfields are preserved as-is. The new version entry in the versions\narray will contain the file-level metadata (filename, mime_type, etc).\nOnly applies when updating an existing entity (_id or file_entity_id is set).\n",
2647
+ "required": false,
2648
+ "schema": {
2649
+ "type": "boolean",
2650
+ "default": false
2651
+ }
2156
2652
  }
2157
2653
  },
2158
2654
  "responses": {
2655
+ "BadRequestError": {
2656
+ "description": "Invalid request parameters or payload",
2657
+ "content": {
2658
+ "application/json": {
2659
+ "schema": {
2660
+ "allOf": [
2661
+ {
2662
+ "$ref": "#/components/schemas/ErrorObject"
2663
+ },
2664
+ {
2665
+ "example": {
2666
+ "status": 400,
2667
+ "error": "Bad Request: filename is required"
2668
+ }
2669
+ }
2670
+ ]
2671
+ }
2672
+ }
2673
+ }
2674
+ },
2675
+ "UnauthorizedError": {
2676
+ "description": "Authentication required or invalid credentials",
2677
+ "content": {
2678
+ "application/json": {
2679
+ "schema": {
2680
+ "allOf": [
2681
+ {
2682
+ "$ref": "#/components/schemas/ErrorObject"
2683
+ },
2684
+ {
2685
+ "example": {
2686
+ "status": 401,
2687
+ "error": "Unauthorized: Invalid or expired token"
2688
+ }
2689
+ }
2690
+ ]
2691
+ }
2692
+ }
2693
+ }
2694
+ },
2695
+ "ForbiddenError": {
2696
+ "description": "Insufficient permissions to access the resource",
2697
+ "content": {
2698
+ "application/json": {
2699
+ "schema": {
2700
+ "allOf": [
2701
+ {
2702
+ "$ref": "#/components/schemas/ErrorObject"
2703
+ },
2704
+ {
2705
+ "example": {
2706
+ "status": 403,
2707
+ "error": "Forbidden: You do not have permission to access this file"
2708
+ }
2709
+ }
2710
+ ]
2711
+ }
2712
+ }
2713
+ }
2714
+ },
2159
2715
  "NotFoundError": {
2160
2716
  "description": "The requested resource was not found",
2161
2717
  "content": {
@@ -2168,7 +2724,27 @@
2168
2724
  {
2169
2725
  "example": {
2170
2726
  "status": 404,
2171
- "error": "Not Found"
2727
+ "error": "Not Found: File entity not found"
2728
+ }
2729
+ }
2730
+ ]
2731
+ }
2732
+ }
2733
+ }
2734
+ },
2735
+ "InternalServerError": {
2736
+ "description": "An unexpected error occurred on the server",
2737
+ "content": {
2738
+ "application/json": {
2739
+ "schema": {
2740
+ "allOf": [
2741
+ {
2742
+ "$ref": "#/components/schemas/ErrorObject"
2743
+ },
2744
+ {
2745
+ "example": {
2746
+ "status": 500,
2747
+ "error": "Internal Server Error"
2172
2748
  }
2173
2749
  }
2174
2750
  ]