---
title: Floyo API - Files
slug: floyo-api-files
docTags: 
createdAt: 2026-04-27T19:36:50.985Z
---

# Introduction

A `file` represents any file used by your workflows. You can download and retrieve a file's metadata from the `/files` resource.



# Browsing files

Browse returns a paginated collection of files and folders for a path in your team's storage. Use query parameters to filter, search, and sort the result set. Pass the `cursor` from a previous response to fetch the next page when `has_more` is `true`.

To browse your files make an **authenticated** `GET` request to `/files`.

:::hint{type="info"}
The `path` query parameter is **required**. Use `/` to list the storage root, or a folder path such as `/inputs`, `/outputs`, or `/inputs/api/uploads`.
:::

****

**QUERY PARAMETERS**

| Parameter         | Required | Value                                                                           | Default           | Description                                                                                                                                                          | Example                                                    |
| ----------------- | -------- | ------------------------------------------------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| `path`            | Yes      | `string`                                                                        | N/A               | Folder path to list. Paths are normalized to a single leading `/` and no trailing `/` (except root `/`). `.` and `..` segments are not allowed.                      | `/files?path=/inputs`                                      |
| `search`          | No       | `string` (3–128 characters)                                                     | N/A               | Case-insensitive search against the file or folder name.                                                                                                             | `/files?path=/inputs&search=landscape`                     |
| `sort`            | No       | `created_at`, `size_bytes`, or `name`, optionally followed by `.asc` or `.desc` | `created_at.desc` | Sort order for the result set. When `sort` is omitted entirely, items are sorted by `created_at` descending (newest first).                                          | `/files?path=/outputs&sort=name.asc`                       |
| `limit`           | No       | integer between `10` and `100`                                                  | `50`              | Maximum number of items to return in a single page.                                                                                                                  | `/files?path=/inputs&limit=75`                             |
| `cursor`          | No       | `string`                                                                        | N/A               | Opaque pagination cursor returned by a previous browse response. Use with the same `path`, filters, search, and sort values as the request that produced the cursor. | `/files?path=/inputs&cursor=eyJpZCI6ImZpbGVfMTIzIn0`       |
| `created_at[gte]` | No       | ISO 8601 datetime or UNIX timestamp in seconds                                  | N/A               | Include items created at or after this timestamp.                                                                                                                    | `/files?path=/inputs&created_at[gte]=1777593599`           |
| `created_at[lte]` | No       | ISO 8601 datetime or UNIX timestamp in seconds                                  | N/A               | Include items created at or before this timestamp. Must be greater than or equal to `created_at[gte]` when both are set.                                             | `/files?path=/inputs&created_at[lte]=2026-04-30T23:59:59Z` |
| `size_bytes[gte]` | No       | integer ≥ 0                                                                     | N/A               | Include items whose size is greater than or equal to this value, in bytes.                                                                                           | `/files?path=/outputs&size_bytes[gte]=1000000`             |
| `size_bytes[lte]` | No       | integer ≥ 0                                                                     | N/A               | Include items whose size is less than or equal to this value, in bytes. Must be greater than or equal to `size_bytes[gte]` when both are set.                        | `/files?path=/outputs&size_bytes[lte]=5000000`             |



**RESPONSE ATTRIBUTES**

| Attribute  | Type               | Description                                                                                                       |
| ---------- | ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| `path`     | `string`           | The normalized folder path that was listed.                                                                       |
| `items`    | `array`            | Array of file and folder objects matching the query.                                                              |
| `cursor`   | `string` \| `null` | Pagination cursor to pass as the `cursor` query parameter on the next request. `null` when there is no next page. |
| `has_more` | `boolean`          | Whether additional items are available beyond the current page.                                                   |



Each object in `items` includes the following attributes:

| Attribute    | Type               | Description                                                                                                                                  |
| ------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | `string`           | Unique ID of the file or folder, e.g., `file_NS8KPRtb8LJjatAA`.                                                                              |
| `object`     | `file` \| `folder` | Returned object type.                                                                                                                        |
| `name`       | `string`           | The file or folder name.                                                                                                                     |
| `type`       | `string`           | For folders, always `folder`. For files, the mime type (e.g., `image/png`).                                                                  |
| `size_bytes` | `integer`          | The size in bytes.                                                                                                                           |
| `full_path`  | `string`           | The full path of the item in team storage (without a leading `/`), e.g., `inputs/api/uploads/landscape.png`.                                 |
| `input_path` | `string`           | Present when the item can be referenced as a workflow input. The path to be used as the **input** file path for any compatible ComfyUI node. |
| `created_at` | `string`           | ISO8601 timestamp when the item was created.                                                                                                 |
| `updated_at` | `string`           | ISO8601 timestamp when the item was last updated.                                                                                            |



**EXAMPLE REQUESTS**

1. List the 25 newest items under `/inputs`:

```curl
curl -X GET "https://api.floyo.ai/files?path=/inputs&sort=created_at.desc&limit=25" \
     -H "Authorization: Bearer <YOUR_API_KEY>" \
     -H "Accept: application/json"
```

2. Search files by name `"dancer"`, created after August 2, 2026 at 14:00 UTC, sorted by size:

:::CodeblockTabs
cURL

```curl
curl -X GET "https://api.floyo.ai/files?path=/inputs&search=dancer&created_at[gte]=2026-08-02T14:00:00Z&sort=size_bytes.desc" \
     -H "Authorization: Bearer <YOUR_API_KEY>" \
     -H "Accept: application/json"
```
:::

3. List 100 files between 5 and 10 megabytes, sorted by oldest first:

:::CodeblockTabs
cURL

```curl
curl -X GET "https://api.floyo.ai/files?path=/inputs&size_bytes[gte]=5000000&size_bytes[lte]=10000000&sort=created_at.asc&limit=100" \
     -H "Authorization: Bearer <YOUR_API_KEY>" \
     -H "Accept: application/json"
```
:::

***

**EXAMPLE RESPONSE**

```curl
{
    "path": "/inputs",
    "items": [
        {
            "id": "file_abc123XYZ789abcd",
            "object": "folder",
            "name": "api",
            "type": "folder",
            "size_bytes": 7482666,
            "full_path": "inputs/api",
            "input_path": "#inputs/api",
            "created_at": "2026-05-12T18:24:19.278928+00:00",
            "updated_at": "2026-05-12T18:24:19.278928+00:00"
        },
        {
            "id": "file_NS8KPRtb8LJjatAA",
            "object": "file",
            "name": "ComfyUI_00994_.png",
            "type": "image/png",
            "size_bytes": 350983,
            "full_path": "inputs/ComfyUI_00994_.png",
            "input_path": "#inputs/ComfyUI_00994_.png",
            "created_at": "2026-04-21T13:55:32.431054+00:00",
            "updated_at": "2026-04-21T13:55:32.431054+00:00"
        }
    ],
    "cursor": "eyJpZCI6ImZpbGVfTlM4S1BSdGI4TEpqYXRBQSJ9",
    "has_more": true
}
```

***

**ERROR RESPONSES**

`STATUS 400`: Invalid query parameters.

```javascript
{
    "error": "Invalid request",
    "message": "One or more request parameters are invalid.",
    "details": {
        "path": "A path is required",
        "limit": "Must be at least 25"
    }
}
```

***

## Browsing Tips & Best Practices

**Start from a known root**

List `/` to discover top-level folders, then drill into `/inputs` or `/outputs` (and nested paths) as needed.

***

**Reuse&#x20;**`input_path`**&#x20;in workflows**

When an item includes `input_path`, you can pass that value directly as the input file path for any compatible ComfyUI node — the same way you would after uploading a file or retrieving file metadata.

***

**Paginate with stable filters**

When following a `cursor`, keep the same `path`, `search`, `sort`, and filter parameters as the request that produced the cursor. Changing them between pages can return unexpected results.



***



# Retrieve File (metadata)

Retrieve a file's metadata with an option to generate a pre-signed URL for easy reference. See [Download File](docId:9dvDMPoOxgp3tHr-hXH_v) if you wish to download the file to your app directly.

To retrieve a `file` make an **authenticated** `GET` request to `/files/:fileId`.


**QUERY PARAMETERS**

| Parameter                  | Required | Value           | Default                 | Description                                                                                                                                                                                  | Example                                                              |
| -------------------------- | -------- | --------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `expand`                   | No       | `presigned_url` | N/A                     | Expand a file response by including a time-limited, pre-signed URL to the file.                                                                                                              | `/files/<FILE_ID>?expand=presigned_url`                              |
| `presigned_url_expires_in` | No       | `number`<br />  | 300 seconds (5 minutes) | The presigned\_url expiration time in second between `30` and `604800` (1 week).<br /><br />The Floyo API will return a validation error if  `expand=outpus.presigned_url` is not specified. | `/files/<FILE_ID>?expand=presigned_url&presigned_url_expires_in=600` |



:::hint{type="warning"}
A **presigned URL** is a time-limited, self-contained URL that carries authentication credentials embedded in it, so the client can access a resource directly without going through your server. Once generated, it is public — anyone in possession of the URL can access the resource without further authentication, until the expiry time passes and the URL becomes invalid.
:::



**RESPONSE ATTRIBUTES**

| Attribute       | Type      | Desription                                                                      |
| --------------- | --------- | ------------------------------------------------------------------------------- |
| `id`            | `string`  | Unique ID of the file, e.g., `file_NS8KPRtb8LJjatAA`                            |
| `object`        | `file`    | Returned object type, always `file`.                                            |
| `file_name`     | `string`  | The file name.                                                                  |
| `mime_type`     | `string`  | The file mime type.                                                             |
| `size_bytes`    | `integer` | The file size in bytes.                                                         |
| `created_at`    | `string`  | ISO8601 timestamp when the file was created.                                    |
| `input_path`    | `string`  | The path to be used as the **input** file path for any compatible ComfyUI node. |
| `presigned_url` | `string`  | The optional public presigned url.                                              |



**EXAMPLE REQUEST:**

:::CodeblockTabs
cURL

```curl
curl -X GET https://api.floyo.ai/files/<FILE_ID>?expand=presigned_url \
     -H "Authorization: Bearer <YOUR_API_KEY>" \
     -H "Accept: application/json"
```
:::

****

**EXAMPLE RESPONSE:**

`STATUS 200`: File retrieved successfully.

```json
{
    "id": "file_NS8KPRtb8LJjatAA",
    "object": "file",
    "file_name": "ComfyUI_00994_.png",
    "mime_type": "image/png",
    "size_bytes": 350983,
    "created_at": "2026-04-21T13:55:32.431054+00:00",
    "input_path": "#inputs/ComfyUI_00994_.png",
    "presigned_url": "https://cdn.floyo.ai/file_NS8KPRtb8LJjatAA?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InYxIn0.eyJmaWxlX2lkIjoiZmlsZV9OUzhLUFJ0YjhMSmphdEFBIiwiYWtfaWQiOiJqNXJncmNuNCIsImp0aSI6ImRhMzgzMTQ1LTU3MTUtNDdjYy1iZTc3LWU4ZmQyOTczODU0NyIsImlzcyI6ImZsb3lvLWFwaSIsImF1ZCI6ImZsb3lvLWNkbiIsInN1YiI6ImZpbGVfYWNjZXNzIiwiaWF0IjoxNzc3MzEwOTg4LCJuYmYiOjE3NzczMTA5ODgsImV4cCI6MTc3NzM3MDk4OH0.6IXOOIUlM-TBuvJ5tCY6W_EAWhOVRpViI4-5WsHUiSM"
}
```



***



# Download File

Download a file from the Floyo CDN.

If you don't want to generate a presigned url for your file but you're still eager to download it, you can make an **authenticated** request to the **Floyo Files CDN**.

:::hint{type="info"}
**Floyo Files CDN** base url: `https://cdn.floyo.ai/`
:::

To download the file make an **authenticated** `GET` request to `https://cdn.floyo.ai/<FILE_ID>/download`

This endpoint streams the file directly from the CDN to the client without buffering it in memory, so download performance is determined by the CDN and not the API server. The CDN independently validates the bearer token, ensuring the file is only served to authenticated requests even if the CDN endpoint were accessed directly.


**EXAMPLE REQUEST:**

:::CodeblockTabs
cURL

```curl
curl -OJ https://cdn.floyo.ai/<FILE_ID>/download \
     -H "Authorization: Bearer <YOUR_API_KEY>"
```
:::

If the authentication passes and the file exists, it will be downloaded to your drive.



***



# Upload File

## Introduction

Th&#x65;**&#x20;Floyo Files API** allows you to upload files directly to your team's storage using a standard `multipart/form-data` request.

Uploaded files can later be referenced inside workflows, reused across runs, or managed through the Files API.

The upload endpoint supports:

- File uploads using `multipart/form-data`
- Custom destination paths
- Optional server-side filename overrides
- Configurable filename conflict handling

***

## Upload Endpoint

To upload a file, make an **authenticated** `POST` request to the **Floyo Files CDN** `/upload` endpoint.

:::hint{type="info"}
**Floyo Files CDN** upload url: `https://cdn.floyo.ai/upload`
:::

***

## Request Format

Uploads must be sent as a `multipart/form-data` request.

### Form Fields

| Parameter     | Required | Type        | Default | Description                           |
| ------------- | -------- | ----------- | ------- | ------------------------------------- |
| `file`        | Yes      | `Blob/File` | N/A     | The file to upload                    |
| `path`        | No       | `String`    | N/A     | Destination path inside `/inputs`     |
| `filename`    | No       | `String`    | N/A     | Override the uploaded filename        |
| `on_conflict` | No       | `String`    | `fail`  | Conflict strategy: `fail` or `rename` |

### Parameters

`file`

The binary file to upload.

This parameter is required and must be sent as a `Blob`, `File`, or binary multipart upload.

***

`path`

Optional destination path where the file should be uploaded.

All uploads are stored under the `/inputs` root directory.

For example, if `path` is set to `/api/uploads` your file will be uploaded to `/inputs/api/uploads`

If omitted, the file will be uploaded to the root `/inputs` directory.

***

`filename`

Optional filename override.

If provided, this value replaces the original uploaded filename.

***

`on_conflict`

Controls how filename conflicts are handled.

Possible values:

| Value    | Description                                                                                                                                                                                                                                                                                  |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fail`   | **Default value**. Reject the upload if a file with the same name already exists on the destination folder.                                                                                                                                                                                  |
| `rename` | Automatically renames the file when a filename conflict occurs by appending an incrementing suffix, and returns the final filename in the response. For example, if `landscape.png` already exists, the uploaded file may be renamed to `landscape (1).png`, `landscape (2).png`, and so on. |

****

**EXAMPLE REQUEST:**

The following example will upload a file named `landscape.png` to the `/inputs/api/uploads` folder, and will be renamed to `beautiful-landscape.png`.  If a file with the same name already exists at the destination, the uploaded file will be automatically renamed to avoid the conflict.

```curl
curl -X POST "https://cdn.floyo.ai/upload" \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -F "file=@./landscape.png" \
  -F "path=/api/uploads" \
  -F "filename=beautiful-landscape.png" \
  -F "on_conflict=rename"
```

***

### Response

`STATUS 200`: File uploaded successfully.&#x20;

Returns the uploaded file metadata. The `input_path` value can be used as the input file path for any compatible ComfyUI node.

```json
{
  id: 'file_fD243HoYG1AGzcD2',
  file_name: 'beautiful-landscape (1).png',
  mime_type: 'image/png',
  created_at: '2026-05-12T18:24:19.278928+00:00',
  size_bytes: 7482666,
  input_path: '#inputs/api/uploads/beautiful-landscape (1).png'
}
```

`STATUS 409`: Filename Conflict.

Returned when `on_conflict=fail` and a file with the same name already exists in the destination directory. The response includes a suggestion field containing the next available filename you can use to retry the upload without conflicts.

```json
{
  "error": "Upload Failed",
  "message": "A file with the same name already exists at the requested path.",
  "suggestion": "beautiful-landscape (1).png"
}
```

***

### Upload Flow Overview

1. Build a `multipart/form-data` request
2. Attach the file using the `file` field
3. Optionally specify `path`, `filename`, and `on_conflict`
4. Send the request to `/upload`
5. Receive the uploaded file metadata

***

## Tips & Best Practices

**Use&#x20;**`rename`**&#x20;for automatic conflict handling**

If your application uploads user-generated content, using:

```text
on_conflict=rename
```

helps avoid upload failures caused by duplicate filenames.

***

**Organize uploads using paths**

Use nested paths to keep uploads organized:

```text
/api/uploads/users
/api/uploads/projects
/api/uploads/generated
```

***

**Preserve original mime types**

Always send the correct mime type when creating the upload blob.

If the mime type cannot be detected, fallback to:

```text
application/octet-stream
```



***



# Deleting files and folders

Delete a file or folder from your team's storage by its unique ID. Files and folders share the same ID format (e.g., `file_NS8KPRtb8LJjatAA`).

To delete a file or folder make an **authenticated** `DELETE` request to `/files/<FILE_ID>`.

:::hint{type="danger"}
Deletion is permanent. Deleted files and folders cannot be recovered through the Floyo API.
:::



**QUERY PARAMETERS**

| Parameter   | Required | Value           | Default | Description                                                                                                                | Example                           |
| ----------- | -------- | --------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `recursive` | No       | `true`, `false` | `false` | When `true`, delete a folder and all of its contents. Required when deleting a non-empty folder. Ignored for file deletes. | `/files/<FILE_ID>?recursive=true` |



**RESPONSE ATTRIBUTES**

When a **file** is deleted:

| Attribute   | Type     | Description                          |
| ----------- | -------- | ------------------------------------ |
| `id`        | `string` | Unique ID of the deleted file.       |
| `object`    | `file`   | Returned object type, always `file`. |
| `full_path` | `string` | The full path of the deleted file.   |



When a **folder** is deleted:

| Attribute      | Type      | Description                                                                                   |
| -------------- | --------- | --------------------------------------------------------------------------------------------- |
| `id`           | `string`  | Unique ID of the deleted folder.                                                              |
| `object`       | `folder`  | Returned object type, always `folder`.                                                        |
| `full_path`    | `string`  | The full path of the deleted folder.                                                          |
| `delete_count` | `integer` | Number of items deleted (including the folder itself and its contents when `recursive=true`). |

***

**EXAMPLE REQUEST:**

Delete a single file:

:::CodeblockTabs
cURL

```curl
curl -X DELETE "https://api.floyo.ai/files/<FILE_ID>" \
     -H "Authorization: Bearer <YOUR_API_KEY>" \
     -H "Accept: application/json"
```
:::

Delete a folder and its contents:

:::CodeblockTabs
cURL

```curl
curl -X DELETE "https://api.floyo.ai/files/<FILE_ID>?recursive=true" \
     -H "Authorization: Bearer <YOUR_API_KEY>" \
     -H "Accept: application/json"
```
:::

***

**EXAMPLE RESPONSES:**

`STATUS 200`: File deleted successfully.

```json
{
    "id": "file_NS8KPRtb8LJjatAA",
    "object": "file",
    "full_path": "outputs/ComfyUI_00994_.png"
}
```

`STATUS 200`: Folder deleted successfully.

```json
{
    "id": "file_fD243HoYG1AGzcD2",
    "object": "folder",
    "full_path": "inputs/api/uploads",
    "delete_count": 12
}
```

`STATUS 403`: Locked item.

Returned when the target item is locked and cannot be deleted.

```json
{
    "error": "Forbidden",
    "message": "This item is locked and cannot be deleted."
}
```

`STATUS 404`: File or folder not found.

```json
{
    "error": "Not Found",
    "message": "The file or folder you requested to delete was not found."
}
```

`STATUS 409`: Folder is not empty.

Returned when deleting a non-empty folder without `recursive=true`.

```json
{
    "error": "Conflict",
    "message": "Folder is not empty. Set recursive=true to delete the folder and its contents."
}
```

***

## Tips & Best Practices

**Prefer deleting by ID from a browse response**

Use **Browsing your files** to locate the item, then pass its `id` to this endpoint. That avoids guessing paths and makes it clear whether you are deleting a file or a folder.

***

**Use&#x20;**`recursive=true`**&#x20;only when you intend to wipe a folder**

Omitting `recursive` (or setting `recursive=false`) protects you from accidentally deleting a folder that still contains files. Set `recursive=true` only when you explicitly want to remove the folder and everything inside it.

***

**Top-level folders are protected**

Root folders such as `inputs` and `outputs` cannot be deleted. Delete specific files or nested folders inside them instead.



