Appearance
Using Files
Cloud Flow can create, read, copy, process, list, and delete files through ioLoop's server-side file capabilities. Use file operations when a Project needs to handle generated documents, uploaded attachments, images, external file content, or downloads as part of trusted backend processing.
Cloud Flow provides Files blocks for common operations and the $io.fs Server API for additional functionality in custom JavaScript. File workflows can also interact with Database records and configured Connections.
This page focuses on choosing and implementing file workflows in Cloud Flow. For exact block inputs and API signatures, see Cloud Flow Files Blocks and the $io.fs Server API.
When to Use Cloud Flow for Files
Use Cloud Flow when a workflow needs to:
- Create a downloadable report, document, or other generated file.
- Read text, JSON, CSV, or other file content for backend processing.
- Work with binary files or streams through supported server-side APIs.
- Copy files between storage locations, including public and private areas.
- Compress or transform an image using supported file operations.
- Retrieve a file from an external URL and save it in Project file storage.
- Inspect, list, or delete stored files.
- Process attachments uploaded through a Form or other supported workflow.
- Associate generated output with a Database record.
- Authorize access before providing a private-file download URL.
- Exchange files with external systems through configured Connections.
Use the Database File Fields guide when the main task is configuring record-associated uploads and their permissions. Use Media when a Creator needs to upload public assets for the frontend.
Understanding File Storage and Access
Several ioLoop capabilities involve files, but they serve different purposes and have different access models.
| Capability | Primary Purpose | Access Consideration |
|---|---|---|
| Frontend Media | Project-owned logos, images, and other browser-loadable assets. | Media files are public frontend resources. |
| Database File Fields | Attachments and other files associated with table records. | Associated files inherit the access rules of their parent Database table. |
| Cloud Flow File Operations | Server-side creation, reading, processing, copying, and distribution of files. | File operations can target public or private cloud storage, as supported by the operation. |
These capabilities can work together. For example, Cloud Flow may generate a report and store a reference to that output in a Database record. However, writing a file through $io.fs does not by itself create a Database record or a file-field association. Configure that separate data operation when the workflow requires it.
Public and Private Cloud File Storage
Supported Files blocks and $io.fs methods distinguish the public and private cloud storage areas.
| Storage | Use When | Important Consideration |
|---|---|---|
| Public | The file is intended to be available through a public URL. | Anyone with an accessible public URL may be able to retrieve the file. |
| Private | Access to the file must be controlled by trusted backend logic. | Cloud Flow should authorize the request before distributing the file or generating a temporary download URL. |
For operations that accept an isPublic value, true selects public storage and false selects private storage. When copying files, the source and destination can have separate public/private selections.
Do not confuse private storage with a private-looking URL. A file saved in public storage remains public even if the Page hides the link. Conversely, a private file can be distributed through an appropriately authorized temporary URL without making the underlying storage public.
Database File Fields Inherit Table Access
Files associated with Database file fields follow their parent table's access rules.
- A table with Public Read makes associated files publicly accessible.
- A table with restricted Read access applies those restrictions to its associated files.
- Create, Update, and Delete permissions also matter for workflows that add, replace, or remove record-associated attachments.
For example, product photographs in a publicly readable Products table may appropriately be public. Identity documents in a publicly readable Applications table would be exposed even if no Page displays their links.
A Cloud Flow authorization check on one download action cannot make an attachment private if the underlying table already permits public access to it. Choose an appropriately restricted table or a private-file storage workflow for sensitive files.
See File Fields and Table Access.
Choosing Files Blocks or the Server API
Cloud Flow can use visual Files blocks, focused custom JavaScript, or a combination of both.
| Need | Recommended Starting Point |
|---|---|
| Create a file from text or a URL | Create File block |
| Read file contents as text | Read File block |
| Copy a file | Copy File block |
| Compress an existing image | Compress File block |
| Download and compress an image | Create Compressed File block |
| Find, list, or delete files | Lookup File, List Files, or Delete File(s) blocks |
| Obtain a public file URL | URL of File (Public) block |
| Work with binary buffers or streams | $io.fs Server API in Custom Code |
| Create a temporary private-file download URL | $io.fs.getFileDownloadUrl(...) in Custom Code |
The visual blocks cover common file operations, while the Server API offers additional methods for text, buffers, streams, and public/private download URLs. Use the implementation style that best fits the workflow.
Files Blocks and Results
Most file-operation blocks provide on success and on error statement areas. Place dependent work inside the appropriate completion path rather than assuming a file operation has finished when the next unrelated block starts.
The File Operation Data block provides data returned by the current file operation, and File Operation Error provides its error information where supported.
For example, a file-generation workflow might follow this conceptual pattern:
text
Create File
On Success
Read File Operation Data
Update the related record
Set the Web Hook success response
On Error
Read File Operation Error
Log a safe diagnostic message
Set the Web Hook error responseThis illustrates workflow responsibilities, not an exact set of block labels for every operation. Refer to the Files block reference for the inputs and result behavior of the selected block.
Creating Files
Choose the source format based on the file content and how it is produced.
| Source | Common Use | Supported Approach |
|---|---|---|
| Text | Reports, CSV text, JSON, generated content. | Create File block or $io.fs.createFileFromText(...) |
| External URL | Save content supplied by a trusted remote source. | Create File block or $io.fs.createFileFromUrl(...) |
| Buffer | Generated binary documents, images, or other binary content. | $io.fs.createFileFromBuffer(...) |
| Readable stream | Large or streamed file content. | $io.fs.createFileFromStream(...) |
Choose a meaningful destination path, appropriate content type, and the intended public/private storage area. Validate or constrain paths and source URLs supplied by users or external systems.
Example: Create a Private Text Report
The following example uses the documented Server API to create a private text file:
js
const path = '/reports/registration-summary.txt';
const content = 'Registration summary\nTotal registrations: 42\n';
const result = await $io.fs.createFileFromText(
path,
content,
'text/plain',
false
);
if (!result.status) {
// Handle result.err and do not report success.
} else {
// The file was created. Store its reference if the workflow needs one.
}The final argument false selects private storage. This code does not automatically associate the file with a Database record or distribute it to a caller. Those are separate workflow steps.
For exact parameters and returned data, see the $io.fs Server API.
Reading and Processing Files
Different operations are appropriate for different kinds of file content.
| Operation | Use It For |
|---|---|
| Read File block | Reading a supported file as text. |
$io.fs.readFileAsText(...) | Reading text content in custom server-side JavaScript. |
$io.fs.readFileAsBuffer(...) | Processing binary data as a Buffer. |
$io.fs.readFileAsStream(...) | Reading file data as a stream for stream-oriented processing. |
Lookup File block or $io.fs.lookupFile(...) | Inspecting file metadata and checking whether a file exists. |
List Files block or $io.fs.listFiles(...) | Retrieving files matching a path/name prefix. |
For example, a backend workflow might read a CSV file, parse its contents using a curated server-side library, validate the records, and then perform permitted Database operations.
Select a processing method appropriate for the expected size and format. Binary data should not be assumed to be text, and reading a very large file entirely into memory may be less appropriate than stream-based processing.
Handle missing files, invalid formats, malformed content, and processing failures explicitly. File existence and valid file contents are separate checks.
Copying, Compressing, and Transforming Files
The Files blocks and Server API support several common processing patterns:
- Copy File copies a file to another path or storage area.
- Compress File compresses an existing image into a destination file using the supported Tinify options.
- Create Compressed File downloads an image from a URL, compresses it, and creates an output file.
- Custom Code can perform additional supported transformations using the curated Node.js runtime and available libraries.
Copying Between Public and Private Storage
Copy operations can identify the source and destination storage areas independently. This allows, for example, processing an image privately and creating a public output when the final asset is intentionally public.
Be careful when copying from private to public storage: the new destination file is publicly accessible, regardless of the original file's private status. Only publish an output after confirming that the contents are suitable for public access.
A copy operation creates another file. Do not assume it removes the source file or updates every Database reference automatically.
Image Compression
The documented image-compression operations use Tinify and require a Tinify API key along with any supported compression, resize, or conversion options.
Keep credentials in trusted backend configuration or a suitable Connection-backed workflow rather than exposing them in frontend code. Test compression failures and the output format, dimensions, quality, and destination path.
For full parameter descriptions, see Cloud Flow Files Blocks and the $io.fs Server API.
Returning Download Links
File generation and file distribution are separate responsibilities.
Before returning access to a protected file, Cloud Flow should validate the caller, the requested record or resource, and the application's authorization rules.
Public Download URLs
For files in public storage, use the URL of File (Public) block or the documented $io.fs.getPublicFileDownloadUrl(path) function to obtain a public URL.
A public URL is appropriate only when the file is intended for public access. Hiding a link in the frontend does not restrict who can retrieve that file.
Temporary Private Download URLs
For private cloud storage, the Server API supports:
js
$io.fs.getFileDownloadUrl(path, isPublic, expires)With isPublic set to false, expires specifies how long the returned URL remains valid, in seconds. The documented range is 1 to 43,200 seconds (12 hours).
For example, after the workflow has verified that the caller is authorized:
js
const privateUrl = await $io.fs.getFileDownloadUrl(
'/reports/registration-summary.txt',
false,
300
);
// Return privateUrl only to the authorized caller.This generates a temporary URL with a five-minute validity period. It does not perform the authorization check. The Cloud Flow must establish access before generating or returning the URL.
Treat temporary URLs as sensitive while valid: someone who obtains a valid URL may be able to use it until expiration. Do not assume the URL is single-use or automatically revoked when the user closes a Page.
For precise behavior, see $io.fs.getFileDownloadUrl.
Associating Files with Database Records
A file workflow may need to save a reference to the generated or processed file in a Database record.
For example, a report-generation workflow may:
- Receive a request for a particular report or record.
- Verify the caller's authorization and validate the request.
- Generate the file in the appropriate storage area.
- Check that file creation succeeded.
- Update the relevant Database record with the supported file reference or metadata.
- Return a suitable result to the caller.
The required Database field value and update operation depend on the selected schema and workflow. Do not assume that a cloud-storage path is automatically a valid Database file-field value or that creating a file updates the related record.
If a Database table is publicly readable, its file-field attachments must also be treated as publicly accessible. Do not use a public-readable file field to expose a private stored file indirectly. Choose a secured table or an appropriately designed private-file workflow instead.
See File Fields and Using Database.
Example: Generating a Private Report
Consider an administrative Page that lets authorized staff generate and download a registration report.
1. Receive the request
A Page calls a Cloud Flow Web Hook with the event or report identifier. Cloud Flow treats that identifier as untrusted input and checks the caller's authorization.
2. Retrieve permitted data
Cloud Flow loads the records needed for the report, using an appropriate query or Server API operation. It returns no protected data if the caller is not authorized.
3. Generate the report
Cloud Flow prepares the report contents and creates a file in private cloud storage. It checks the file-operation result before continuing.
4. Record the result where needed
If the application keeps a report history, Cloud Flow stores the appropriate report metadata or file reference in a Database record using a supported data operation.
5. Provide controlled access
After confirming authorization, Cloud Flow generates a temporary private-file download URL and returns it to the authorized caller. The Page offers the resulting download without exposing backend credentials.
6. Handle failures
Cloud Flow returns an appropriate error if data retrieval, file generation, or record updates fail. The Page shows a useful message rather than assuming the report was generated.
This pattern separates trusted data access, private storage, record association, and file delivery instead of relying on a public link for sensitive content.
File Lifecycle and Cleanup
Plan the complete file lifecycle, including creation, processing, distribution, replacement, and deletion.
| Operation | What to Verify |
|---|---|
| Create | The content, destination path, storage area, and content type are correct. |
| Read or process | The file exists, uses the expected format, and can be processed safely. |
| Copy or replace | The destination access level is intentional and references are updated as needed. |
| Download | Public/private storage and caller authorization match the requirement. |
| Delete | The intended file is removed and any dependent record or workflow references are handled. |
| Retry or failure | A repeated operation does not unintentionally create duplicates or leave inconsistent state. |
Cloud Flow provides Delete File(s) blocks and $io.fs.deleteFile(...) or $io.fs.deleteFiles(...) for supported deletion workflows.
Do not assume that deleting a Database record automatically removes every underlying stored file, or that deleting a file automatically clears references held in Database records. Verify the deletion and cleanup behavior of the workflow in use.
When files have already been distributed through public or temporary URLs, consider those outstanding links and the underlying storage access before changing or removing the file.
Access and Security
File workflows must respect both storage access and application authorization.
Before reading, returning, copying, or deleting a protected file:
- Determine whether the file is public, private, or associated with a table record.
- Establish the caller's identity and permissions where required.
- Validate record IDs, file paths, and other caller-supplied values.
- Avoid exposing files through overly broad table permissions or public destinations.
- Return only the file or metadata the caller is permitted to receive.
- Do not expose private credentials, raw sensitive files, or unrestricted file listings in logs or frontend responses.
Treat external URLs and uploaded file contents as untrusted inputs. Where files are retrieved from remote URLs, constrain the allowed sources as appropriate to the application; do not let arbitrary user-supplied URLs become unrestricted backend fetch requests.
For sensitive workflows, see Access Security and Table Access.
Testing File Workflows
Test file behavior through the actual Page, Web Hook, Background Task, or external system that invokes it.
| Test | What to Verify |
|---|---|
| Successful creation | Correct contents, file path, content type, and public/private setting. |
| Missing source | A missing file or unavailable URL produces an appropriate error. |
| Different file sizes | Small and large files can be processed within the supported runtime. |
| Invalid content | Incorrect file formats and malformed content are handled safely. |
| Private download | Authorized callers receive appropriate temporary URLs; unauthorized callers do not. |
| Public download | Public URLs are used only for files intended to be shared publicly. |
| Record association | Stored references and metadata match the generated files. |
| Repeated execution | Retries do not create unwanted copies or inconsistent records. |
| Cleanup | Files and dependent Database references are handled as intended. |
During Preview, built-in Database operations automatically use the development database. However, this rule alone does not establish that all file storage, Cloud Flow behavior, or external Connection operations are isolated from production. Verify the actual file destination, Cloud Flow test/live context, and external service settings before performing operations with side effects.
Use Testing and Logs for backend diagnostics, and Previewing for Page-level testing.
Troubleshooting
| Issue | What to Check |
|---|---|
| File creation fails | Destination path, storage selection, supplied content, source URL, and returned error. |
| File not found | Exact path, public/private selection, and whether the file was created successfully. |
| Unexpected public access | Public storage selection, destination copies, and parent table Read permissions. |
| Private download fails | File location, authorization logic, generated URL, and expiration. |
| Downloaded content is incorrect | Source data, format, content type, and transformation results. |
| Generated file not visible in a record | Whether the workflow separately updated the record with the correct supported file reference. |
| Processing fails for large files | Whether a buffer-based approach is appropriate or a stream-based API should be used. |
| Deletion leaves a broken reference | Whether the Database record or other consumers still point to the removed file. |
| Files differ between test and published workflows | Storage destination, runtime environment, Database context, and Connections used. |
Use file operation results and Cloud Flow logs to identify the failure. Avoid logging file contents, private download URLs, or credentials.
Good Practices
- Choose storage intentionally. Decide whether a file is public, private, or governed by Database table access before creating it.
- Prefer built-in file blocks for common operations. Use
$io.fswhen buffers, streams, private download URLs, or specialized behavior require it. - Authorize before distributing private files. Generating a temporary URL is not an authorization check.
- Keep record association explicit. Writing a file and updating a Database file field are separate operations.
- Use appropriate processing methods. Choose text, buffers, or streams based on the content and workload.
- Handle success and failure paths. Do not assume asynchronous file processing has completed until it reports a result.
- Avoid exposing private files accidentally. Recheck access when copying files or changing public/private destinations.
- Manage cleanup. Review orphaned files, old references, and duplicate outputs.
- Test with realistic files and users. Include unauthorized access and failure cases.
Common Mistakes
Avoid these patterns:
- Treating Media, Database File Fields, and Cloud Flow public/private storage as the same access model.
- Assuming file-field attachments are private when their table permits Public Read.
- Creating a sensitive file in public storage and hiding its link in the Page.
- Copying a private file into public storage without checking the contents.
- Returning private-file download URLs without checking caller authorization.
- Assuming that creating a file automatically updates its associated Database record.
- Assuming that deleting a record automatically deletes the underlying file.
- Using a text-only operation to process binary content.
- Ignoring File Operation Error or other documented failure results.
- Treating successful Preview Database isolation as proof that external file or provider operations are isolated.
- Logging sensitive content, private links, or credentials.
Cloud Flow file workflows are most reliable when file creation, storage access, record association, authorization, processing, and delivery are treated as distinct responsibilities.

