Skip to main content

Files endpoints

Use the /files endpoints to upload, list, download, and delete files stored by SkillFlaw.

The examples below use x-api-key authentication. Both /api/v1/files and /api/v2/files are authenticated endpoints.

Differences between /v1/files and /v2/files

SkillFlaw currently exposes two file APIs with different responsibilities:

  • /api/v1/files is the workflow-scoped interface. It addresses files by {flow_id} and file name and is still the simplest option when you need flow-relative paths such as Chat Input image uploads.
  • /api/v2/files is the database-backed file management interface. It addresses files by file UUID, records tenant/business/workflow scope, supports rename, batch download, batch delete, and append uploads.

For POST /api/v2/files, you must provide one of these contexts:

  • a flow_id query parameter for a flow you own; or
  • scope headers such as tenant-id (optionally plus business-id and is-self).

If you send session_id, you must also send flow_id.

The upload size limit for both versions is controlled by SKILLFLAW_MAX_FILE_SIZE_UPLOAD.

Files/V1 endpoints

Upload file (v1)

Upload a file to a flow you own. If the flow does not exist or does not belong to the authenticated user, the backend returns 404. This route also accepts an optional session_id query parameter to tag the stored file metadata with a workflow session.


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/files/upload/$FLOW_ID" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-F "file=@notes.txt"

Result

_10
{
_10
"flowId": "92f9a4c5-cfc8-4656-ae63-1f0881163c28",
_10
"file_path": "92f9a4c5-cfc8-4656-ae63-1f0881163c28/2026-04-28_10-35-12_notes.txt"
_10
}

Upload image files (v1)

Use the same endpoint to upload an image and pass the returned file_path into a flow run. This is the documented path for Chat Input style image uploads.

  1. Upload the image:


    _10
    curl -X POST \
    _10
    "$SKILLFLAW_URL/api/v1/files/upload/$FLOW_ID" \
    _10
    -H "x-api-key: $SKILLFLAW_API_KEY" \
    _10
    -F "file=@PATH/TO/diagram.png"

  2. Reuse the returned file_path in a flow run:


    _14
    curl -X POST \
    _14
    "$SKILLFLAW_URL/api/v1/run/$FLOW_ID?stream=false" \
    _14
    -H "Content-Type: application/json" \
    _14
    -H "x-api-key: $SKILLFLAW_API_KEY" \
    _14
    -d '{
    _14
    "output_type": "chat",
    _14
    "input_type": "chat",
    _14
    "tweaks": {
    _14
    "ChatInput-b67sL": {
    _14
    "files": "92f9a4c5-cfc8-4656-ae63-1f0881163c28/2026-04-28_10-35-12_diagram.png",
    _14
    "input_value": "Describe this image"
    _14
    }
    _14
    }
    _14
    }'

List files (v1)

List the file names stored for a flow you own.


_10
curl -X GET \
_10
"$SKILLFLAW_URL/api/v1/files/list/$FLOW_ID" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY"

Result

_10
{
_10
"files": [
_10
"2026-04-28_10-35-12_notes.txt",
_10
"2026-04-28_10-36-01_diagram.png"
_10
]
_10
}

Download file (v1)

Download a file from a flow you own.


_10
curl -X GET \
_10
"$SKILLFLAW_URL/api/v1/files/download/$FLOW_ID/2026-04-28_10-35-12_notes.txt" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
--output downloaded-notes.txt

Delete file (v1)

Delete a file from a flow you own.


_10
curl -X DELETE \
_10
"$SKILLFLAW_URL/api/v1/files/delete/$FLOW_ID/2026-04-28_10-35-12_notes.txt" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY"

Result

_10
{
_10
"message": "File 2026-04-28_10-35-12_notes.txt deleted successfully"
_10
}

Files/V2 endpoints

/api/v2/files stores file metadata in the database and returns canonical file records. List operations are always limited to files created by the current user.

Upload file (v2)

Upload a file into a scoped SkillFlaw file namespace.

If you upload with the same base name in the same namespace and append=false, SkillFlaw auto-renames the new record by appending (n) before the extension.


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v2/files" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "tenant-id: $TENANT_ID" \
_10
-F "file=@engine-manual.pdf"

Optional query parameters:

Query parameterTypeDescription
flow_idUUIDBind the upload to a workflow and resolve scope from that flow when scope headers are absent.
session_idUUIDFurther scope the file to a workflow session. Only valid when flow_id is present.
file_typestringOverride the stored media type metadata.
appendbooleanAppend bytes to an existing file with the same logical name in the same namespace. Extensions must match.
Result

_14
{
_14
"id": "d44dc2e1-9ae9-4cf6-9114-8d34a6126c94",
_14
"tenant_id": "07e5b864-e367-4f52-b647-a48035ae7e5e",
_14
"business_id": 0,
_14
"flow_id": null,
_14
"session_id": null,
_14
"file_scope": 2,
_14
"c_uid": 1,
_14
"name": "engine-manual",
_14
"path": "07e5b864-e367-4f52-b647-a48035ae7e5e/d44dc2e1-9ae9-4cf6-9114-8d34a6126c94.pdf",
_14
"size": 851160,
_14
"file_type": "application/pdf",
_14
"created_at": "2026-04-28T10:42:01"
_14
}

Upload a workflow-scoped file (v2)

If you want the file record tied directly to a workflow or workflow session, pass flow_id and optionally session_id.


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v2/files?flow_id=$FLOW_ID&session_id=$SESSION_ID" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-F "file=@knowledge-base.csv"

This stores the file with file_scope = 3 and a logical path you can pass into components such as Read File.

Send files to your flows (v2)

For components that accept logical file paths, upload with /api/v2/files and pass the returned path into your run payload.


_16
curl -X POST \
_16
"$SKILLFLAW_URL/api/v1/run/$FLOW_ID" \
_16
-H "Content-Type: application/json" \
_16
-H "x-api-key: $SKILLFLAW_API_KEY" \
_16
-d '{
_16
"input_value": "Summarize the uploaded file",
_16
"output_type": "chat",
_16
"input_type": "text",
_16
"tweaks": {
_16
"Read-File-1olS3": {
_16
"path": [
_16
"07e5b864-e367-4f52-b647-a48035ae7e5e/d44dc2e1-9ae9-4cf6-9114-8d34a6126c94.pdf"
_16
]
_16
}
_16
}
_16
}'

List files (v2)

List the current user's file records. If you omit scope headers, SkillFlaw returns all files created by the current user across scopes.


_10
curl -X GET \
_10
"$SKILLFLAW_URL/api/v2/files" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY"

Result

_16
[
_16
{
_16
"id": "c7b22c4c-d5e0-4ec9-af97-5d85b7657a34",
_16
"tenant_id": "07e5b864-e367-4f52-b647-a48035ae7e5e",
_16
"business_id": 0,
_16
"flow_id": null,
_16
"session_id": null,
_16
"file_scope": 2,
_16
"c_uid": 1,
_16
"name": "engine-manual",
_16
"path": "07e5b864-e367-4f52-b647-a48035ae7e5e/c7b22c4c-d5e0-4ec9-af97-5d85b7657a34.pdf",
_16
"size": 851160,
_16
"file_type": "application/pdf",
_16
"created_at": "2026-04-28T10:42:01"
_16
}
_16
]

Download file (v2)

Download a file by its UUID. SkillFlaw resolves the stored media type automatically: images are served inline, other file types are served as attachments.


_10
curl -X GET \
_10
"$SKILLFLAW_URL/api/v2/files/$FILE_ID" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
--output downloaded-file.pdf

Edit file name (v2)

Change the logical name of a file. The file UUID and storage path stay the same.


_10
curl -X PUT \
_10
"$SKILLFLAW_URL/api/v2/files/$FILE_ID?name=new-file-name" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "tenant-id: $TENANT_ID"

Delete file (v2)

Delete a single file by UUID.


_10
curl -X DELETE \
_10
"$SKILLFLAW_URL/api/v2/files/$FILE_ID" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "tenant-id: $TENANT_ID"

Result

_10
{
_10
"detail": "File engine-manual deleted successfully"
_10
}

Download multiple files as a zip (v2)

Submit a JSON array of file UUIDs to POST /api/v2/files/batch/ to receive a zip archive.


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v2/files/batch/" \
_10
-H "Content-Type: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-d '[
_10
"c7b22c4c-d5e0-4ec9-af97-5d85b7657a34",
_10
"76543e40-f388-4cb3-b0ee-a1e870aca3d3"
_10
]' \
_10
--output skillflaw-files.zip

Delete multiple files (v2)

Submit a JSON array of file UUIDs to DELETE /api/v2/files/batch/.


_10
curl -X DELETE \
_10
"$SKILLFLAW_URL/api/v2/files/batch/" \
_10
-H "Content-Type: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "tenant-id: $TENANT_ID" \
_10
-d '[
_10
"c7b22c4c-d5e0-4ec9-af97-5d85b7657a34",
_10
"76543e40-f388-4cb3-b0ee-a1e870aca3d3"
_10
]'

Result

_10
{
_10
"message": "2 files deleted successfully",
_10
"files_deleted": 2,
_10
"files_kept": 0
_10
}

Delete all files (v2)

Delete all file records owned by the current user in the current filter scope.


_10
curl -X DELETE \
_10
"$SKILLFLAW_URL/api/v2/files" \
_10
-H "accept: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "tenant-id: $TENANT_ID"

Result

_10
{
_10
"message": "All 3 files deleted successfully",
_10
"files_deleted": 3,
_10
"files_kept": 0
_10
}

  • GET /api/v1/files/images/{flow_id}/{file_name} renders an uploaded image directly for browser use.
  • GET /api/v1/files/profile_pictures/list lists built-in profile pictures.
  • GET /api/v1/files/profile_pictures/{folder_name}/{file_name} fetches a built-in profile picture.
  • POST /api/v1/files/profile_pictures/upload uploads a user profile picture.
  • GET /api/v1/files/profile_pictures/uploaded/by-id/{file_id} fetches an uploaded profile picture by file ID.

See also