Share Management Purpose-built portals for exchanging files with internal teams and external guests.
Shares are purpose-built portals for exchanging files with internal teams and external guests. They support branded file preview, download controls, guest access, password protection, expiration, AI-powered features, and real-time collaboration.
Share Types
| Type | Direction | Description | Guest Uploads | "Anyone with the link" Access |
|---|---|---|---|---|
send | Owner → Guest | Owner distributes files; guests can download only | No | Allowed |
receive | Guest → Owner | Owner collects files; guests can upload only | Yes | Not allowed |
exchange | Bidirectional | Both parties can upload and download | Yes | Not allowed |
Default share type is exchange.
Storage Modes (Immutable at Creation)
Portal (storage_mode=independent, default)
The share has its own isolated storage. Files added to the portal are independent of any workspace. Changes to workspace files do not affect the portal, and vice versa.
Features: Expiration dates, archiving, password protection (Send type only), custom branding, guest access, inline file preview, download controls, post-download messaging, AI auto-titling.
Shared Folder (storage_mode=workspace_folder)
The share is backed by a specific workspace folder. The share displays the live contents of that folder — files added, updated, or removed in the workspace folder are immediately reflected in the share. No file duplication, so no extra storage cost.
Creation: Pass folder_node_id={folder_opaque_id} to link an existing folder, or create_folder=true with folder_name to create a new one.
Restrictions: Expiration dates and archiving are not allowed since the content is live. Each workspace folder can only be shared once. If the backing folder is deleted, the share becomes orphaned (is_orphaned: true in details response).
Both modes look the same to share recipients — a branded portal with file preview, download controls, and all share features.
Response Field: share_category
API responses include a share_category field alongside storage_mode. The storage_mode field is the input parameter used when creating shares; share_category is response-only.
storage_mode | share_category |
|---|---|
independent | portal |
workspace_folder | shared_folder |
Access Options
The access_options parameter controls who can access the share:
| Value | Description |
|---|---|
'Only members of the Share or Workspace' | Most restrictive (default). Only explicit members or workspace members. |
'Members of the Share, Workspace or Org' | Org members can also access |
'Anyone with a registered account' | Any authenticated Fastio user |
'Anyone with the link' | Public access. Enables password protection (Send type only). |
Restrictions:
- Receive and Exchange shares cannot use
'Anyone with the link'unlessanonymous_uploads_enabledis true (requires premium plan). Without anonymous uploads, file uploads require user identity. - Enabling comments or certain notification settings on a share with
'Anyone with the link'access automatically upgrades access to'Anyone with a registered account'because those features require user identity. - Changing share type to
receiveorexchangewhile access is'Anyone with the link'automatically upgrades access to'Anyone with a registered account'(unlessanonymous_uploads_enabledis true). - Changing access away from
'Anyone with the link'or changing type away from Receive/Exchange automatically disablesanonymous_uploads_enabled.
Compact Responses (output=)
Every endpoint that returns one or more share objects (details, list, discovery) accepts an optional output query parameter that selects the response shape. A single detail-level token may be combined with modifier tokens; specifying two detail levels (e.g. ?output=terse,standard) returns HTTP 400. When output= is omitted, responses are full and byte-for-byte unchanged.
| Level | Fields returned on each share (cumulative) |
|---|---|
terse | id, title, share_type, share_level, share_root_id (the share-root node id as a top-level scalar — member-only; guests do not receive this field), creator (scalar user id) |
standard | terse + share_category, storage_mode, folder_node_id, full share_link object, parent linkage, lifecycle flags (including locked, admin-only), custom_name, custom_url, description, download_security, expires, created, updated, guest_chat_enabled/anonymous_uploads_enabled flags, user_status, intelligence, workflow |
full | standard + capabilities, permission blocks, activity tracking, comments, event_flow, filesystem, invite, member_visibility, multiplayer, chat, search, assets, workflow_permissions, access_options, display_type, branding (accent color, logo, background), password, platform, notify, link_1/link_2/link_3, owner_defined, deleted, storage, suspended, parents |
Use terse for share pickers, share-link previews, and navigation sidebars — it carries the ID, title, type (Send/Receive/Exchange), access level, the share's root node id as a top-level share_root_id scalar (what layouts and transfer pages need to scope navigation), and a creator user id so "Shared by {creator}" rows can resolve via the user cache without pulling the full share-link object. Use standard for share list views and the summary card on share detail pages — it adds storage mode, folder binding, the full share_link object, timestamps, expiration, the caller's membership status, the locked lifecycle chip (admin-only), and the download_security badge (high/medium/off) that share-list rows render. Use full (or omit the parameter) for the share settings screen, branding editors, password configuration, invite link management, and any workflow that reads capability or permission matrices. Unknown tokens are silently ignored. Add the markdown modifier (e.g. ?output=standard,markdown) to receive the response as GitHub-flavored Markdown (Content-Type: text/markdown; charset=UTF-8) instead of JSON — see the cross-cutting ?output= reference for the full contract.
Create Share
Create a new share in a workspace. Auth required.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| {workspace_id} | string | Yes | 19-digit numeric workspace profile ID |
Required Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| intelligence | string | Yes | Boolean string ("true" / "false"). Enable AI indexing. Setting "true" requires both the content_ai and ai_agent plan features; plans without both will be rejected with 1605 (Invalid Input). Portal (independent) shares only — workspace folder shares cannot enable intelligence. |
Optional Parameters
| Parameter | Type | Default | Constraints | Description |
|---|---|---|---|---|
| share_type | string | exchange | send, receive, exchange | Share direction type |
| access_options | string | Only members of the Share or Workspace | See Access Options | Who can access the share |
| invite | string | owners | owners, guests | Who can manage share invitations |
| storage_mode | string | independent | independent, workspace_folder | Storage mode (immutable after creation) |
| folder_node_id | string | — | Valid opaque ID | Workspace folder opaque ID (required for workspace_folder if not creating) |
| create_folder | string | — | Boolean string | Create a new backing folder (with folder_name) |
| folder_name | string | Shared Folder | Not blank | Name for the new backing folder (with create_folder=true) |
| title | string | — | 2-80 chars | Share display title |
| description | string | — | 10-500 chars | Share description |
| custom_name | string | Auto-generated | 10-100 chars, URL-friendly | URL-friendly custom name. Auto-generated opaque ID if omitted. |
| password | string | — | 4-128 chars | Password. Only with Send type + 'Anyone with the link' access. |
| expires | string | — | datetime | Expiration date. Portal mode only. |
| notify | string | never | never, notify_on_file_received, notify_on_file_sent_or_received | Notification preference |
| comments_enabled | string | — | Boolean string | Enable comments |
| download_security | string | — | high, medium, off | Download security level. high: downloads disabled. medium: downloads require a short-lived nonce. off: downloads unrestricted. |
| guest_chat_enabled | string | — | Boolean string | Enable guest AI chat |
| display_type | string | — | Not blank | Visual display mode (grid, list) |
| workspace_style | string | — | Not blank | Workspace visual style |
| accent_color | string | — | Valid JSON | JSON color object for accent |
| background_color1 | string | — | Valid JSON | JSON color object for primary background |
| background_color2 | string | — | Valid JSON | JSON color object for secondary background |
| background_image | integer | — | Numeric, validated range | Background image selection |
| link_1 | string | — | Valid JSON | JSON link object (custom link #1) |
| link_2 | string | — | Valid JSON | JSON link object (custom link #2) |
| link_3 | string | — | Valid JSON | JSON link object (custom link #3) |
| owner_defined | string | — | Valid JSON or "null" | Custom owner-defined properties |
| anonymous_uploads_enabled | string | false | Boolean string | Enable anonymous file uploads. Receive/Exchange + 'Anyone with the link' + premium plan only. |
Request Example
curl -X POST "https://api.fast.io/current/workspace/1234567890123456789/create/share/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "share_type=send&intelligence=true&access_options=Anyone+with+the+link&title=Client+Deliverables"
Response
Status: 200 OK
{
"result": true,
"share": {
"id": "9876543210987654321",
"custom_name": "aB3cD4eF5g",
"storage_mode": "independent",
"share_category": "portal"
}
}
For workspace folder shares, the response also includes folder_node_id.
Response Fields
| Field | Type | Description |
|---|---|---|
response.share.id | string | 19-digit share profile ID |
response.share.custom_name | string | URL name (custom or auto-generated) |
response.share.storage_mode | string | independent or workspace_folder |
response.share.share_category | string | portal (independent) or shared_folder (workspace_folder). Response-only. |
response.share.folder_node_id | string | Backing folder node ID (workspace_folder only) |
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | An invalid share custom name was supplied. | Custom name fails validation |
| 400 | 1605 (Invalid Input) | An invalid share expiration date was supplied. | Invalid datetime format |
| 400 | 1605 (Invalid Input) | Password can only be set for shares with 'Anyone' access option. | Password on non-public share |
| 400 | 1605 (Invalid Input) | Receive and Exchange shares cannot have 'Anyone' access option... | Public access on receive/exchange |
| 400 | 1605 (Invalid Input) | Workspace folder shares cannot have an expiration date... | Expiration on workspace_folder share |
| 400 | 1605 (Invalid Input) | Must provide folder_node_id or set create_folder=true... | Missing folder config for workspace_folder mode |
| 403 | 1685 (Feature Limit) | The organization has reached its share creation limit... | Share quota exceeded for billing plan |
| 406 | 1658 (Not Acceptable) | The supplied share custom name is already in use. | Duplicate custom name |
| 406 | 1658 (Not Acceptable) | This folder has already been shared. | Folder already linked to another share |
| 409 | 1660 (Conflict) | Unable to process share creation request due to concurrent operation. | Concurrent operation conflict |
| 500 | 1663 (Update Failed) | There was an internal error processing your create request. | Internal error |
Share Details
Get full share details. Auth required (optional for public shares). {share_id} accepts a 19-digit numeric ID or a custom name.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| {share_id} | string | Yes | 19-digit share profile ID or custom name |
Request Example
curl -X GET "https://api.fast.io/current/share/1234567890123456789/details/" \
-H "Authorization: Bearer {jwt_token}"
Response
Status: 200 OK
{
"result": true,
"share": {
"id": "1234567890123456789",
"title": "Q4 Financial Reports",
"description": "Quarterly financial documents",
"share_type": "exchange",
"custom_name": "q4-reports",
"storage_mode": "independent",
"share_category": "portal",
"closed": false,
"archived": false,
"share_level": "owner",
"share_root_id": "node_abc123def456",
"download_security": "off",
"activity_tracking": {
"enabled": true,
"owner_activity": true,
"guest_activity": true,
"own_activity": true,
"all_upload_activity": false
},
"comments": {
"enabled": true,
"owner_comments_visible": true,
"guest_comments_visible": true,
"personal_replies_visible": true,
"owner_replies_visible": true
},
"filesystem": {
"file_creation": true,
"file_modification": "owned",
"file_download": "all",
"file_view": "all",
"folder_creation": true,
"folder_modification": "owned"
},
"event_flow": {
"enabled": true,
"can_see_own_events": true,
"can_see_owner_events": true,
"can_see_guest_events": false
},
"multiplayer": {
"enabled_for_user": true,
"enabled_for_owners": true,
"enabled_for_guests": true,
"owners_can_see_guests": true,
"guests_can_see_owners": false
},
"member_visibility": {
"user_can_see_members": true,
"owners_can_see_members": true,
"guests_can_see_members": false
},
"invite": {
"setting": "owners_only",
"can_invite": true
},
"capabilities": {
"can_archive": true,
"can_set_expiration": true
},
"parent_type": "workspace",
"parent_workspace": "9876543210987654321",
"parent_org": "1122334455667788990",
"created": "2024-01-01 10:00:00 UTC",
"expires": "2024-12-31 23:59:59 UTC"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
response.share.id | string | Share profile ID |
response.share.title | string|null | Display title |
response.share.description | string|null | Share description |
response.share.share_type | string | send, receive, or exchange |
response.share.custom_name | string|null | URL-friendly custom name |
response.share.storage_mode | string | independent or workspace_folder |
response.share.share_category | string | portal (independent) or shared_folder (workspace_folder). Response-only. |
response.share.closed | boolean | Whether the share has been soft-deleted |
response.share.archived | boolean | Whether the share is archived |
response.share.share_level | string | Current user's access level: owner, guest, public, excluded |
response.share.share_root_id | string|null | Node OpaqueId of the share's root folder (graft point). Top-level scalar form of share_link.graft_point. Member-only. Returned only when the caller has at least share-member access. |
response.share.download_security | string | Download security level: high, medium, or off |
response.share.activity_tracking | object | Activity visibility settings |
response.share.comments | object | Comment visibility and permission settings |
response.share.filesystem | object | File and folder operation permissions |
response.share.event_flow | object | Real-time event visibility settings |
response.share.multiplayer | object | Real-time collaboration/presence settings |
response.share.member_visibility | object | Who can see other share members |
response.share.invite | object | Invitation policy settings |
response.share.capabilities | object | Operations allowed based on storage mode |
response.share.parent_type | string|null | workspace or user |
response.share.parent_workspace | string|null | Parent workspace ID (workspace-owned shares only) |
response.share.parent_org | string|null | Parent organization ID (workspace-owned shares only) |
response.share.created | string | Creation timestamp (YYYY-MM-DD HH:MM:SS UTC) |
response.share.expires | string|null | Expiration timestamp, or null |
response.share.folder_node_id | string|null | Backing folder node ID (workspace_folder only) |
response.share.is_orphaned | boolean | Whether backing folder was deleted (workspace_folder only) |
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 401 | 1650 (Authentication Invalid) | Authentication required | Non-public share without auth |
| 403 | 144499 | You do not have permissions to view this share. | Lacks view permission |
Public Share Details
Returns a comprehensive view of a share from a single API call. Includes share details, owner information, file listing, member list, and comments. No auth required (optional; enhances permissions if provided).
For password-protected shares, pass the password JWT in the x-ve-password header (obtained from the password auth endpoint).
Request Example
# Public access (no auth)
curl -X GET "https://api.fast.io/current/share/1234567890123456789/public/details/"
# Password-protected share
curl -X GET "https://api.fast.io/current/share/1234567890123456789/public/details/" \
-H "x-ve-password: {password_jwt_token}"
# Authenticated user
curl -X GET "https://api.fast.io/current/share/1234567890123456789/public/details/" \
-H "Authorization: Bearer {jwt_token}"
Response
Status: 200 OK
{
"result": true,
"share": {
"id": "1234567890123456789",
"title": "Q4 Financial Reports",
"share_type": "exchange",
"storage_mode": "independent",
"share_category": "portal"
},
"owner": {
"id": "9988776655443322110",
"display_name": "Jane Smith",
"avatar": "https://..."
},
"nodes": [
{
"id": "aB3cD4eF5g",
"name": "report.pdf",
"type": "file",
"size": 1048576,
"parent": "root"
}
],
"users": [
{
"id": "1122334455667788990",
"display_name": "John Doe",
"role": "guest"
}
],
"comments": [],
"org": {
"id": "5566778899001122334",
"name": "Acme Corp"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
response.share | object | Full share details (same as details endpoint) |
response.owner | object | Share owner's user resource |
response.nodes | array | Top-level files and folders in the share root |
response.users | array | Share members (if user has member visibility permission) |
response.comments | array | Comments on the share (filtered by visibility permissions) |
response.org | object|null | Organization resource (only for workspace-owned shares) |
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 403 | 183836 | You do not have permissions to view this share. | Lacks public view permission |
| 500 | 121168 | Failed to access share storage | Internal storage error |
Update Share
Update share settings. Auth required. Owner/admin only. Supports partial updates. Works on archived shares.
Request Body (All Fields Optional)
| Parameter | Type | Constraints | Description |
|---|---|---|---|
| name | string | Not blank | Share display name |
| title | string | Not blank, or "null" to clear | Display title (2-80 chars) |
| description | string | "null" or "" to clear | Share description (10-500 chars) |
| custom_name | string | 10-100 chars, or "null" to clear | URL-friendly custom name. Must be unique. |
| share_type | string | send, receive, exchange | Share direction type |
| access_options | string | See Access Options | Who can access the share |
| invite | string | owners, guests | Who can manage invitations |
| password | string | 4-128 chars, "null"/"" to clear | Password. Only with Send type + 'Anyone with the link'. |
| expires | string | datetime, "null" to clear | Expiration. Portal mode only. |
| notify | string | See notification values | Notification preference |
| comments_enabled | string | Boolean string | Enable/disable comments |
| download_security | string | high, medium, off | Download security level. high: downloads disabled. medium: downloads require a short-lived nonce. off: downloads unrestricted. |
| display_type | string | grid, list | Visual display mode |
| workspace_style | string | Not blank | Workspace visual style |
| guest_chat_enabled | string | Boolean string | Enable/disable guest AI chat |
| intelligence | string | Boolean string | Can be toggled. Setting "true" requires both content_ai and ai_agent plan features. Disabling flushes embeddings; re-enabling re-indexes (costs AI credits). |
| accent_color | string | JSON or "null" | JSON color object for accent |
| background_color1 | string | JSON or "null" | JSON color object for primary background |
| background_color2 | string | JSON or "null" | JSON color object for secondary background |
| background_image | integer | Numeric, validated range | Background image selection |
| link_1 | string | JSON or "null" | JSON link object (custom link #1) |
| link_2 | string | JSON or "null" | JSON link object (custom link #2) |
| link_3 | string | JSON or "null" | JSON link object (custom link #3) |
| owner_defined | string | JSON or "null" | Custom owner-defined properties |
| share_link_node_id | string | "null" only | Can only be set to "null" to remove workspace share link node |
| anonymous_uploads_enabled | string | Boolean string | Enable/disable anonymous file uploads. Receive/Exchange + 'Anyone with the link' + premium plan only. Automatically disabled when access changes from "Anyone" or type changes from Receive/Exchange. |
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/update/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "title=Updated+Title&description=New+description&share_type=exchange"
Response
Status: 200 OK
{
"result": true
}
Important Behaviors
- Password auto-clear: Changing access away from
'Anyone with the link'automatically clears the password. - Access auto-upgrade: Enabling comments or notification settings that require user identity automatically upgrades access from
'Anyone with the link'to'Anyone with a registered account'. - Share type auto-upgrade: Changing to
receiveorexchangewhile access is'Anyone with the link'upgrades access to'Anyone with a registered account'. - Intelligence: Can be enabled and disabled. Enabling requires both the
content_aiandai_agentplan features — plans that lack either are rejected with1605 (Invalid Input). Disabling destroys indexed embeddings (vector index is flushed). Re-enabling incurs re-indexing costs (AI credits consumed to re-index all files). - Expiration: Workspace folder shares cannot have expiration dates. Expiration is validated against the billing plan.
- Share link sync: Updating the share name automatically renames any associated workspace share link node.
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | An invalid share custom name was supplied. | Invalid or duplicate custom name |
| 400 | 1605 (Invalid Input) | An invalid share expiration date was supplied. | Invalid datetime format |
| 400 | 1605 (Invalid Input) | Password can only be set for shares with 'Anyone' access option. | Password on non-public share |
| 400 | 1605 (Invalid Input) | Intelligence cannot be enabled on workspace folder shares... | Intelligence enable on a workspace_folder share |
| 400 | 1605 (Invalid Input) | Intelligence requires a plan with agentic AI support. | Plan missing content_ai or ai_agent (cannot set intelligence=true) |
| 412 | 1685 (Feature Limit) | Intelligence setting can only be changed twice per minute and five times per hour. Please wait and try again. | Intelligence toggle throttled (per-share limit) |
| 400 | 1605 (Invalid Input) | Workspace folder shares cannot have an expiration date... | Expiration on workspace_folder share |
| 400 | 1605 (Invalid Input) | Receive and Exchange shares cannot have 'Anyone' access option... | Public access on receive/exchange |
| 403 | 144499 | You do not have permissions to access this share. | User lacks admin permission |
| 406 | 1658 (Not Acceptable) | The supplied share custom name is already in use. | Duplicate custom name |
| 500 | 1663 (Update Failed) | There was an internal error processing your update request. | Internal error |
Delete Share
Soft-delete (close) a share. Auth required. Owner/admin only. Requires confirmation.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| confirm | string | Yes | Must match either the share's custom_name (case-insensitive) or its numeric id. Send as a query-string parameter (?confirm=...) — a request body is not read on this DELETE. Safety check. |
Request Example
curl -X DELETE "https://api.fast.io/current/share/1234567890123456789/delete/?confirm=my-share-name" \
-H "Authorization: Bearer {jwt_token}"
Response
Status: 202 Accepted
{
"result": true
}
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 406 | 130987 | The confirm field is required. Pass the share's custom_name or numeric id as the confirm query parameter. | confirm not supplied as a query parameter |
| 406 | 10571 | The confirm field provided does not match the share's custom_name or id. | Confirmation mismatch |
| 403 | 144499 | You do not have permissions to access this share. | Lacks admin permission |
| 500 | 1663 (Update Failed) | There was an internal error processing your request. | Internal error |
Notes
- Soft delete with retention period before permanent removal.
- For workspace folder shares, the share reference in the backing folder is cleaned up.
- Share link nodes in the parent workspace are also removed.
Archive / Unarchive
Archive or unarchive a share. Auth required. Owner/admin only. Portals only — workspace folder shares cannot be archived.
No request body required.
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/archive/" \
-H "Authorization: Bearer {jwt_token}"
Response
Status: 202 Accepted
{
"result": true
}
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | Workspace folder shares cannot be archived... | workspace_folder share |
| 400 | 1663 (Update Failed) | The share is already archived. / The share is not archived. | Wrong current state |
| 403 | 144499 | You do not have permissions to access this share. | Lacks admin permission |
Notes
- Archived shares block guest access.
- Unarchiving requires that the billing plan supports this feature.
Password Protection
Available only on Send shares with 'Anyone with the link' access.
Set/Update Password
Set via password parameter on create or update (4-128 chars). Send "null" or "" to clear.
Authenticate with Password
Authenticate with a share password to get a scoped JWT token. No user auth required.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| password | string | Yes | Share password |
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/auth/password/" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "password=mysecretpassword"
Response
Status: 200 OK
{
"result": true,
"expires_in": 86400,
"auth_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
response.expires_in | integer | Token lifetime in seconds (86400 = 24 hours) |
response.auth_token | string | JWT token to use in x-ve-password header |
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | Input validation | Password is required for authentication. | Missing password field |
| 401 | 1650 (Authentication Invalid) | This share does not require password authentication. | Not password-protected or not public |
| 406 | 1658 (Not Acceptable) | Invalid password provided for this share. | Wrong password |
| 500 | 1654 (Internal Error) | Failed to create authentication token. | JWT creation failure |
Notes
- Token expires after 24 hours.
- If the share's password is changed, all previously issued tokens become invalid.
- Use the returned token in the
x-ve-passwordheader for subsequent share requests.
Anonymous File Drop (Guest Auth)
Enables anonymous file uploads on public Receive and Exchange shares without requiring account registration. Visitors obtain a scoped JWT via the guest auth endpoint, then use it as a Bearer token for subsequent upload requests.
Requirements:
- Share must have
'Anyone with the link'access - Share must be Receive or Exchange type
anonymous_uploads_enabledmust be true on the share- Premium plan required
Authenticate as Guest
Obtain a scoped JWT for anonymous file uploads. Creates an ephemeral user account. No user auth required.
Request
No body required. POST request only.
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/auth/guest/"
Response
Status: 200 OK
{
"result": true,
"auth_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600
}
Response Fields
| Field | Type | Description |
|---|---|---|
response.auth_token | string | Scoped JWT for anonymous uploads (use as Bearer token) |
response.expires_in | integer | Token lifetime in seconds |
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 401 | 1650 (Authentication Invalid) | Anonymous uploads are not enabled for this share. | Feature not enabled or share not eligible |
| 412 | 1685 (Feature Limit) | Anonymous uploads require a premium plan. | Org not on premium plan |
| 429 | 1671 (Rate Limited) | Rate limit exceeded | Too many requests from this IP |
| 500 | 1654 (Internal Error) | Failed to create authentication token. | JWT creation failure |
Notes
- The returned
auth_tokenshould be used as a Bearer token in theAuthorizationheader for subsequent upload requests. - Each guest auth call creates a new ephemeral user account scoped to the share.
- Tokens are short-lived; obtain a new token if the previous one expires.
Anonymous Upload Workflow
- Check share eligibility:
GET /current/share/{share_id}/public/details/— verifyanonymous_uploads_enabled: truein the response. - Obtain guest token:
POST /current/share/{share_id}/auth/guest/— returns a scopedauth_token. - Upload files: Use the standard upload flow (
POST /current/upload/init/, chunk upload,POST /current/upload/complete/) withAuthorization: Bearer {auth_token}. - Add to share:
POST /current/share/{share_id}/storage/addfile/with the upload key, using the same Bearer token.
Expiration
Available only on portal shares (not workspace folder).
Set the expires parameter (datetime format: YYYY-MM-DD HH:MM:SS) on create or update. Send "null" to clear. When the share expires, access is revoked. Expiration is validated against the billing plan.
Branding & Styling
Shares support custom branding through the update endpoint:
| Parameter | Type | Description |
|---|---|---|
accent_color | string | JSON color object for accent |
background_color1 | string | JSON color object for primary bg |
background_color2 | string | JSON color object for secondary bg |
background_image | integer | Background image selection (numeric) |
link_1 | string | JSON link object (custom link #1) |
link_2 | string | JSON link object (custom link #2) |
link_3 | string | JSON link object (custom link #3) |
Send "null" for any JSON field to clear it.
Share Assets
List Available Asset Types
Returns the schema of available asset types (e.g., logo, background). No auth required.
List Share Assets
List assets set on a share. Auth required. Owner/admin only.
Upload/Set Asset
Upload an asset (multipart/form-data). Auth required. Owner/admin only.
| Field | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | The asset file to upload |
| metadata | JSON | No | Optional metadata for the asset |
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/assets/logo/" \
-H "Authorization: Bearer {jwt_token}" \
-F "file=@logo.png" \
-F 'metadata={"crop_x": 0, "crop_y": 0}'
Delete Asset
Remove an asset. Auth required. Owner/admin only.
Read Asset Binary
Returns raw binary data of a share asset. Auth optional for public shares. Works on archived shares.
| Query Parameter | Type | Required | Description |
|---|---|---|---|
| width | integer | No | Requested width (max 4096). Background images only. |
| height | integer | No | Requested height (max 4096). Background images only. |
Share Members
Permission Levels
| Level | Value | Description |
|---|---|---|
| Owner | 1000 | Full control and ownership |
| Admin | 500 | Administrative access, manage members |
| Member | 100 | Standard member access (default for new) |
| Guest | 50 | Limited guest access |
| View | 20 | Read-only access |
Notification Options
| Value | Description |
|---|---|
"Do not notify me" | No notifications |
"Notify me in app" | In-app only (default) |
"Notify me in app and via email" | In-app and email |
"Notify me via app, email and text message" | All notification channels |
Add Member or Send Invitation
Use a 19-digit user ID to add an existing user directly, or an email address to send an invitation. Auth required. Owner/admin only.
Request Body (Adding Existing User)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| permissions | string | No | member | owner, admin, member, guest, view. Cannot be owner (use transfer). |
| notify_options | string | No | "Notify me in app" | Notification preference |
| expires | string | No | — | Membership expiration (YYYY-MM-DD HH:MM:SS UTC). null or "" to clear. |
| force_notification | boolean | No | — | Resend notification email (60-second cooldown after initial add). |
Request Body (Inviting by Email)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| permissions | string | No | member | Permission level for the invitation |
| message | string | No | — | Custom message for the invitation email |
| invitation_expires | string | No | — | Invitation expiration datetime |
Request Example
# Add existing user by ID
curl -X POST "https://api.fast.io/current/share/1234567890123456789/members/9876543210987654321/" \
-H "Authorization: Bearer {jwt_token}" \
-d '{"permissions": "member"}'
# Invite by email
curl -X POST "https://api.fast.io/current/share/1234567890123456789/members/newuser@example.com/" \
-H "Authorization: Bearer {jwt_token}" \
-d '{"permissions": "guest", "message": "Join our shared files!"}'
Response (Invitation Created)
{
"result": true,
"invitation": {
"id": "5566778899001122334",
"inviter": "Jane Smith",
"invitee_email": "newuser@example.com",
"invitee_uid": null,
"accepted_uid": null,
"entity_type": "share",
"share": {
"id": "1234567890123456789",
"name": "Project Files"
},
"state": "pending",
"consumed": false,
"created": "2025-01-15 10:30:00 UTC",
"updated": "2025-01-15 10:30:00 UTC",
"expires": "2025-02-15 10:30:00 UTC"
}
}
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1680 (Cannot Add As Owner) | Adding a member as an owner is not allowed | Tried to add as owner |
| 400 | 1605 (Invalid Input) | You cannot create a membership for the share owner. | Target is share owner |
| 400 | 1605 (Invalid Input) | You cannot add, update, or delete a membership with a higher permission... | Permission exceeds caller |
| 403 | 1680 (Access Denied) | You do not have permission to manage the members of this Share. | Lacks member edit permission |
| 403 | 1685 (Feature Limit) | Share invitation limit reached: X of Y invitations used | Invitation quota exceeded |
Remove Member
Remove a member. Auth required. Owner/admin only. Cannot remove the last owner.
Leave Share (Self-Removal)
Leave a share. Auth required. Owners cannot leave; must transfer ownership first. Works on archived/expired shares.
Member Details
Get detailed membership info for a specific user. Auth required.
Response
{
"result": true,
"user": {
"id": "9876543210987654321",
"account_type": "human",
"email_address": "member@example.com",
"first_name": "John",
"last_name": "Doe",
"permissions": "admin",
"status": "active",
"invite": null,
"notify": "Notify me in app",
"expires": null
}
}
Update Member
Update permissions, notification settings, or expiration. Auth required. Owner/admin only.
| Field | Type | Required | Description |
|---|---|---|---|
| permissions | string | No | admin, member, guest, view. Cannot set to owner. |
| notify_options | string | No | Notification preference |
| expires | string | No | Membership expiration datetime. null/"" to clear. |
Transfer Ownership
Transfer share ownership to another member. Auth required. Owner only. Current owner is demoted to admin.
List Members
List all members. Auth required.
Response
{
"result": true,
"users": [
{
"id": "1111111111111111111",
"account_type": "human",
"email_address": "owner@example.com",
"first_name": "Jane",
"last_name": "Smith",
"permissions": "owner",
"status": "active",
"invite": null,
"notify": "Notify me in app",
"expires": null
},
{
"id": "5566778899001122334",
"account_type": "human",
"email_address": "invited@example.com",
"first_name": "invited@example.com",
"last_name": "",
"permissions": "guest",
"status": "pending",
"invite": {
"id": "5566778899001122334",
"created": "2025-01-15 10:30:00 UTC",
"expires": "2025-02-15 10:30:00 UTC"
},
"notify": "Notify me in app",
"expires": null
}
]
}
Pending Members
When a user is invited to a share by email but does not yet have a Fastio account, they appear as a pending member in the member list. Pending members are placeholders that allow teams to pre-assign workflow items before the invitee signs up.
How pending members appear in responses:
- The
statusfield is"pending"(vs"active"for registered users). - An
inviteobject is included with basic invitation details (id,created,expires). email_addressshows the invited email address.first_nameis set to the invited email address;last_nameis empty.
Workflow assignments: On a share, guests (including still-pending invitees) have no workflow access — they cannot be assigned to an approval, task, or todo step, and share guests cannot use the Tasks API. Workflow approval reviewers must be workspace members; external non-member reviewers require the workspace's native-review tier to be extended. Newly created workspaces default to the extended tier (external reviewers available out of the box); a workspace that predates that default, or whose tier was explicitly set to mvs or cleared, supports external reviewers only after a workspace admin sets the extended tier via the workspace update endpoint.
Account claim: When the invited user signs up or accepts the invitation with an existing account, their status transitions from "pending" to "active". Their share access is preserved across the transition.
Removal: To remove a pending member, delete their invitation using the invitation endpoints (see List Invitations, Delete Invitation below). Deleting the invitation removes the pending member and unassigns any workflow items associated with them.
Notifications: Pending members do not receive in-app or email notifications until they claim their account.
Join Share
Join a share via self-join or invitation. Auth required.
Self-join rules (without invitation key):
| Access Option | Who Can Self-Join |
|---|---|
'Only members of the Share or Workspace' | Members of the share or its parent workspace |
'Members of the Share, Workspace or Org' | Members of the share, parent workspace, or parent org |
| Other values | Self-join blocked; invitation required |
Self-joined members receive member permission with no expiration. Only notify_options is respected from input.
List Invitations
List invitations, optionally filtered by state (pending, accepted, declined). Auth required.
Update Invitation
Update an invitation. {invitation_id} can be a numeric ID or an email address. Auth required.
| Field | Type | Required | Description |
|---|---|---|---|
| state | string | No | pending, accepted, declined |
| permissions | string | No | Updated permission level: admin, member, guest, view |
| notify_options | string | No | Updated notification preference |
| expires | string | No | Updated membership expiration datetime |
Delete Invitation
Revoke an invitation. {invitation_id} can be a numeric ID or an email address. Auth required.
Share Discovery
List All Shares
List all accessible shares (joined, invited, owned). Auth required. Orphaned workspace folder shares are automatically filtered out.
Response Fields
Each share in the shares array includes the same fields as the details endpoint, plus:
| Field | Type | Description |
|---|---|---|
shares[].user_status | string | User's membership status (e.g., joined, invited) |
shares[].folder_node_id | string|null | Backing folder node ID (workspace_folder only) |
shares[].is_orphaned | boolean | Whether backing folder was deleted |
List Available Shares
List shares the user has joined or owns (excludes pending invitations). Auth required. Does not include parent workspace/org information.
Check Share Name Availability
Check if a share custom name is available. Auth required.
Status 202 Accepted = name available.
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | An invalid share name was supplied. | Fails validation |
| 406 | 1658 (Not Acceptable) | The supplied share name is already in use. | Name already taken |
List Shares in Workspace
List shares belonging to a workspace. Auth required. Paginated with offset-based pagination.
| Query Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Number of results to return |
| offset | integer | No | Number of results to skip |
| archived | string | No | Boolean string. Filter by archived state. |
List User's Shares
List all shares accessible to the current user (owned, joined, invited). Auth required. Paginated. Includes parent workspace and org information.
| Query Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Number of results to return |
| offset | integer | No | Number of results to skip |
| archived | string | No | Boolean string. Filter by archived state. |
Import Share into Workspace
Import a user-owned share into a workspace. Auth required. Caller must be the share owner with no other co-owners. The share must currently be user-owned (not already in a workspace). Archived shares are automatically unarchived during import.
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | This share is not owned by you and cannot be imported. | Share not user-owned |
| 400 | 1605 (Invalid Input) | The share has multiple owners... | Multiple co-owners exist |
| 403 | 1685 (Feature Limit) | The workspace has reached its share limit. | Share quota exceeded |
| 500 | 1654 (Internal Error) | Failed to import the share to the workspace. | Internal error |
Share AI
Shares support AI features when intelligence is enabled. Enabling intelligence and creating or sending chat messages require plan features (content_ai plus ai_agent for write/agentic flows). See the AI reference for the full plan matrix.
Auto-Generate OG Image
Generate an Open Graph image for the share. Auth required.
Auto-Generate Title & Description
Generate a title and description for the share based on its contents. Auth required.
AI Chat
Share AI chat follows the same patterns as workspace AI chat. Replace /workspace/{id} with /share/{id} in all chat endpoints. For full AI chat documentation, see AI & Chat reference.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /current/share/{share_id}/ai/chat/ | Create chat |
| GET | /current/share/{share_id}/ai/chat/list/ | List chats |
| GET | /current/share/{share_id}/ai/chat/{chat_id}/details/ | Chat details |
| POST | /current/share/{share_id}/ai/chat/{chat_id}/update/ | Update chat |
| DELETE | /current/share/{share_id}/ai/chat/{chat_id}/ | Delete chat |
| POST | /current/share/{share_id}/ai/chat/{chat_id}/message/ | Send message |
| GET | /current/share/{share_id}/ai/chat/{chat_id}/messages/list/ | List messages |
| GET | /current/share/{share_id}/ai/chat/{chat_id}/message/{msg_id}/details/ | Message details |
| GET | /current/share/{share_id}/ai/chat/{chat_id}/message/{msg_id}/read/ | Stream response (SSE) |
| POST | /current/share/{share_id}/ai/chat/{chat_id}/publish/ | Publish chat (currently disabled platform-wide — returns 403) |
| POST | /current/share/{share_id}/ai/share/ | AI share markdown |
QuickShare (Workspace Feature)
Deprecated — use File Share. Creating or extending a QuickShare now returns 403 with a directed message pointing to POST /current/workspace/{workspace_id}/create/fileshare/. The durable File Share replaces it. Existing QuickShare links can still be viewed, downloaded, and revoked during the drain; the public read endpoints below remain live until the existing population reaches its natural expiry.
QuickShare creates a temporary public link for a single file. This is a workspace storage feature, not a share management feature, but is related to sharing.
Create QuickShare (deprecated → 403)
Deprecated. Returns 10756 (Quickshare Deprecated) (403) for the create and extend-expiry paths. Use POST /current/workspace/{workspace_id}/create/fileshare/ instead. The historical constraints (single file, max 1 GB, expires / expires_at) no longer apply because creation is closed.
QuickShare Details (Public)
Returns metadata including file information, creator, expiration, and download limit status. No auth required.
Response
{
"result": true,
"quickshare": {
"id": "aBcDeFgHiJ",
"node": {
"id": "1234567890123456789",
"type": "file",
"name": "presentation.pdf",
"size": 5242880,
"mimetype": "application/pdf",
"mimecategory": "document"
},
"creator_uid": {
"id": "9876543210987654321",
"account_type": "human",
"first_name": "Jane",
"last_name": "Doe"
},
"limit_exceeded": false,
"expires": "2024-01-15 13:30:00 UTC",
"created": "2024-01-15 10:30:00 UTC"
}
}
Download File (Public)
Returns raw binary file content with Content-Type and Content-Disposition headers. No auth required.
Transfer Limits:
- Max total bytes: 10 GB
- Max multiplier: 100x file size
- Once either limit is reached,
limit_exceededis set permanently.
Read Note Content (Public)
Reads the content of a note/markdown file as JSON. Returns the sanitized markdown content as a string along with the note resource. No auth required.
Response
{
"result": true,
"content": "# Note content here\n\nMarkdown text...",
"note": {
"id": "{opaque_note_id}",
"type": "note",
"name": "my-note.md",
"size": 1024,
"mimetype": "text/markdown",
"mimecategory": "document"
}
}
Error responses: Returns 1605 (Invalid Input) (400) if the node is not a note, 1609 (Not Found) (404) if the quickshare is not found or the note is in trash, 1656 (Bandwidth Limit) (429) if the transfer limit is reached, or 1680 (Access Denied) (403) if the file is inaccessible (virus/DMCA/locked).
Preview File (Public)
Preview types: binary, thumbnail, image, hls_stream, pdf, spreadsheet, audio, mp4. No auth required.
Preview Limits: Max 20x file size for total preview bytes.
Multi-file previews (e.g., HLS) return a 307 Temporary Redirect to a sub-file endpoint.
QuickShare Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | Validation error | Invalid opaque ID |
| 404 | 1609 (Not Found) | Quickshare not found. | No such QuickShare |
| 429 | 1656 (Bandwidth Limit) | You have exceeded the bandwidth policy for this Quickshare. | Transfer limit reached |
| 403 | 1680 (Access Denied) | You have reached the maximum number of previews for this Quickshare. | Preview limit reached |
| 422 | 1698 (Unprocessable Entity) | The source file is corrupt or unreadable and cannot be previewed. | Source is corrupt/truncated; do not retry |
File Share (Durable Single-File Share)
A File Share is the durable successor to QuickShare: a long-lived, link-shareable view of one file from a workspace. Unlike QuickShare it is durable by default (expiry is optional, never forced) and has no per-link transfer cap — bandwidth is metered to the owning organization. A File Share is bound to a single workspace file node at creation; the binding is immutable (rebinding means creating a new File Share).
Addressing — opaque id. A File Share is addressed by an opaque public id (the id_alt field): an unguessable, non-enumerable handle (the same id shape used for nodes and uploads), which appears in its share links. Every File Share route — public read and management alike — accepts this opaque id; the legacy numeric profile id is also accepted during the transition, so existing links keep working. Build links from id_alt.
Access Tiers
Set with access_option at create/update time:
| Tier | Value | Who can open the link |
|---|---|---|
| Anyone with link | anyone_with_link | Anyone, no account required (anonymous) |
| Any registered | any_registered | Any authenticated Fastio user |
| Named people | named_people | Only users explicitly granted access (the default) |
On top of the tier, per-user grants raise an individual user's capability — view, download, or edit. An optional link password can gate any tier; it is supplied on the public read endpoints via the x-ve-password request header, never in the URL.
Workspace members (implicit access). The shared file lives in the File Share's parent workspace, so an authenticated member of that workspace reaches it through the File Share exactly as they would through the workspace itself — admitted regardless of tier or named grant, at the capability their workspace role confers on the file (a workspace editor gets edit, a view-only member gets view). This is why the owner/creator and other workspace members can view — and collaboratively edit notes on — their own named_people share without granting themselves. A set link password still applies to members. Anonymous callers and non-members are governed solely by the tier + grant rules above.
Public Read Endpoints
These serve the link viewer. They are anonymous-allowed where the access tier permits (e.g. anyone_with_link); for any_registered / named_people the caller must present a bearer token and have sufficient access.
Viewer metadata and the bound file's public node metadata (name / size / type) — never the workspace path or owning-profile ids.
The effective_capability field is the single highest capability the calling identity actually holds on this File Share — view, download, or edit — resolved after the access tier, any per-user grant, and the link password are all applied. Use it to render the right controls up front (show the Download button only at download or higher; show “Upload new version” only at edit) instead of attempting an action and handling a later denial. Because the details response is only returned once the caller has passed the read gate, the value is present and at least view on the normal path; it is omitted only in the rare case the capability probe itself faults — treat an absent value as “unknown” and fall back to attempting the action.
Manage context (authenticated callers only). The details response additionally carries an optional manage block so an owner’s UI can decide whether to surface in-place management controls without a separate lookup:
can_manage(boolean) —truewhen the authenticated caller may manage this File Share (a member of its parent workspace, the same requirement the management endpoints enforce),falsewhen authenticated but not a manager. Omitted entirely for anonymous callers, so the public link stays anonymous.workspace_id(string) — the owning workspace id, returned only whencan_manageistrue. Pass it to the workspace-scoped management endpoints (list / update / grants / delete). A non-manager never receives it.creator_uid(string) — the File Share creator’s user id, returned only whencan_manageistrue.
These fields are additive — anonymous viewers and clients that ignore them are unaffected.
Details Response (authenticated manager)
{
"result": true,
"fileshare": {
"fileshare": "1234567890123456789",
"id_alt": "a2bk7yqe9z3w8h5n6m4xp1c0tv7rs",
"title": "Quarterly Presentation",
"access_option": "anyone_with_link",
"has_password": false,
"effective_capability": "download",
"can_manage": true,
"workspace_id": "9876543210987654321",
"creator_uid": "1122334455667788990",
"file": {
"id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjf",
"type": "file",
"name": "presentation.pdf",
"size": 5242880,
"mimetype": "application/pdf"
}
}
}
For an anonymous viewer the three manage fields are absent; for an authenticated non-manager only can_manage: false is present (no workspace_id / creator_uid).
Download the bound file (raw binary with Content-Type and Content-Disposition headers). Requires the download capability.
Preview the bound file (view capability). Preview types match the storage preview surface (thumbnail, image, pdf, mp4, hls_stream, etc.). Multi-file previews (e.g. HLS) return a 307 Temporary Redirect to a sub-file endpoint.
List the bound file's versions (view capability) and download a specific historical version (download capability). Read-only — there is no restore/promote on the public surface.
Management Endpoints (Authenticated Workspace Member)
Creating, listing, updating, deleting, and managing grants are documented in the Workspaces reference (POST /current/workspace/{workspace_id}/create/fileshare/, GET /current/workspace/{workspace_id}/list/fileshares/, and the POST|PATCH /current/fileshare/{id}/update/, DELETE /current/fileshare/{id}/delete/, GET|POST|DELETE /current/fileshare/{id}/grants/ endpoints). All require the caller to be an authenticated member of the File Share's parent workspace.
External Edit (Write-Back)
A holder of an edit grant can replace the shared file's content without being a workspace member, by targeting the File Share id as the update target of a normal upload session. This is covered in the Upload reference (action=update, instance_id={fileshare_id}, file_id={bound_node_id}), including the optional if_version_id compare-and-swap precondition and how a version conflict is surfaced.
Collaborative Notes (Realtime)
When the bound file is a note (a .md text document), an authorized recipient can read and collaboratively edit it in real time rather than downloading and re-uploading binary content. Real-time edits from a File Share recipient and from members of the owning workspace converge on the same live document — there is no forking or separate copy. A note bound to a File Share cannot be replaced by a binary upload; its content changes only through the endpoints below or the real-time collaboration session.
The flow is: mint a short-lived collaboration token with the note-auth endpoint, then use that token (not your session bearer token) to read the note's text and, if you hold an edit grant, to push updates. The same token is what a client presents to join the real-time collaboration session.
Mint a short-lived (15-minute) collaboration token for the bound note. The caller must be signed in and must pass the File Share's access gate — including the x-ve-password header when the link is password-protected. The token grants editing when the caller holds an edit grant on the File Share or is a workspace member whose role confers edit on the file; otherwise a read-only token is returned. Anonymous anyone-with-link visitors cannot mint a token (they use the read-only download/preview surface above).
Note-Auth Response
{
"expires_in": 900,
"auth_token": "..."
}
Return the note's current text content along with a safe metadata summary of the note. Requires the collaboration token from the note-auth endpoint — this is not a session endpoint, so a session bearer token alone is not accepted. Pass an optional version_id query parameter to read a historical version instead of the live content.
Replace the note's text content and/or rename it. Requires an edit collaboration token (a read-only token is rejected). Send the note name and content in the request body. An empty or whitespace-only content value is rejected as invalid input. Supply the optional if_version_id precondition to perform a compare-and-swap; on a version conflict the endpoint returns 409 with the current version so the client can rebase and retry.
Owner-Side Visibility (Comments)
A File Share is a view of a file that also lives in the owning workspace, so comments left by File Share recipients are visible to workspace members on that same file — it's the same node, so the comments appear in both places. For a workspace member:
- Activity feed — File Share comment activity surfaces on the owning workspace's realtime / activity feed, so workspace members see when a recipient comments (the nudge carries no comment text).
- File comments — the workspace node comment list for the bound file includes the File Share's comments alongside the workspace's own. They appear read-only in the workspace view (
can_reply/can_edit/can_deletearefalse) — replies and edits to a File Share comment go through the File Share's own surface. - Workspace search — the workspace
commentssearch bucket includes comments left through the workspace's live (active, non-expired, non-revoked) File Shares.
This visibility is one-directional: workspace ⊇ File Share. Workspace members see File Share comments, but File Share recipients never see the workspace's internal comments — a recipient's view stays isolated to their own File Share's comment thread.
File Share Error Responses
| HTTP Status | Code | Cause |
|---|---|---|
| 400 | 1605 (Invalid Input) | Invalid id or input value |
| 401 | 1650 (Authentication Invalid) | A link password is required and was missing or wrong (present it via the x-ve-password header) |
| 403 | 1700 (Forbidden) | The access tier or named grant does not permit the caller |
| 404 | 1609 (Not Found) | No such File Share, or the bound file content is no longer available |
Share Workflow
Shares support the Tasks feature (task lists) when workflow is enabled. Workflow requires the workflow billing plan feature, which is also required for workflow orchestration.
Enable Workflow
Enable workflow features on a share. Auth required. Admin only. Idempotent — returns success if already enabled.
Response
Status: 200 OK
{
"result": true,
"message": "Workflow features enabled",
"workflow": true
}
Disable Workflow
Disable workflow features on a share. Auth required. Admin only. Idempotent — returns success if already disabled.
Response
Status: 200 OK
{
"result": true,
"message": "Workflow features disabled",
"workflow": false
}
List Task Lists
List all task lists for a share. Auth required. Workflow view permission required. Supports offset-based pagination (limit/offset). Supports format=markdown query parameter for markdown output.
Response
Status: 200 OK
{
"result": true,
"task_lists": [
{
"id": "aBcDeFgHiJ",
"profile_id": "1234567890123456789",
"name": "Sprint 1",
"description": "First sprint tasks",
"created_by": "9876543210987654321",
"properties": {},
"sort_order": 0,
"created": "2026-01-15 10:30:00 UTC",
"updated": "2026-01-15 10:30:00 UTC",
"deleted": null
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1
}
}
Create Task List
Create a new task list in a share. Auth required. Workflow modify permission required. Request body is JSON.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Task list name |
| description | string | No | Task list description |
| properties | object | No | Custom properties (default {}) |
| sort_order | integer | No | Sort position (default 0) |
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/tasks/create/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"name": "Sprint 1", "description": "First sprint tasks"}'
Response
Status: 200 OK
{
"result": true,
"task_list": {
"id": "aBcDeFgHiJ",
"profile_id": "1234567890123456789",
"name": "Sprint 1",
"description": "First sprint tasks",
"created_by": "9876543210987654321",
"properties": {},
"sort_order": 0,
"created": "2026-01-15 10:30:00 UTC",
"updated": "2026-01-15 10:30:00 UTC",
"deleted": null
}
}
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | Invalid task list name | Name fails validation |
| 400 | 1605 (Invalid Input) | Invalid description | Description fails validation |
| 400 | 1605 (Invalid Input) | Invalid JSON in request body | Malformed JSON body |
Reorder Task Lists
Bulk reorder task lists within a share. Auth required. Workflow modify permission required. Request body is JSON. Prevents concurrent reordering.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| order | array | Yes | Non-empty array of {id, sort_order} objects |
Each entry in order:
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Task list opaque ID |
| sort_order | integer | Yes | New sort position |
Request Example
curl -X POST "https://api.fast.io/current/share/1234567890123456789/tasks/reorder/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"order": [{"id": "aBcDeFgHiJ", "sort_order": 0}, {"id": "kLmNoPqRsT", "sort_order": 1}]}'
Response
Status: 200 OK
{
"result": true,
"reordered": 2,
"profile_id": "1234567890123456789"
}
Error Responses
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 400 | 1605 (Invalid Input) | order must be a non-empty array of {id, sort_order}... | Missing or empty order array |
| 400 | 1605 (Invalid Input) | Each order entry must have id and sort_order fields... | Malformed entry |
| 400 | 1605 (Invalid Input) | Task list ID ... does not belong to this share | ID not owned by this share |
Workflow-Native Sign-off & Checklists
For human sign-off on a share's files use workflow review via either approval step type — both produce a reviewer roster, version-pinned assets, a per-reviewer per-asset decision matrix, and a resolution policy. The lock-based approval step pulls the reviewed files into workspace storage and write-locks them while the review is pending, releasing them on resolution. The in-place approval_in_place step instead reviews the files where they already live in the share/portal/file share with no move/copy/lock — the approved version is version-stamped and content-hashed for durable audit and later changes surface as drift. The fastest way to start an in-place review on a single file is the "Request approval" quick path (POST /current/workflow-review/quick-approval/), which provisions a private file share for the chosen reviewers and starts a one-step in-place approval run in a single call (single file, members-only roster in v1; for multi-file or external reviewers, author an approval_in_place step in a workflow). For checklist items use the workflow todo step (both step types in the workflow orchestration tool). The Tasks API (task lists & tasks) is the supported task-tracking surface. See the Workflow reference for these surfaces.
Workflow Error Responses (Shared)
All workflow endpoints (tasks, enable/disable) share these common errors:
| HTTP Status | Code | Message | Cause |
|---|---|---|---|
| 403 | 144499 | You do not have permissions to access this share. | Lacks admin permission (enable/disable) |
| 403 | — | Workflow features are only available to share members... | Lacks workflow view/modify permission |
| 412 | 1685 (Feature Limit) | Workflow feature not available | Billing plan does not include workflow |
Share Storage
Share storage follows the same API patterns as workspace storage. See Storage reference for full endpoint documentation.
Replace /workspace/{workspace_id} with /share/{share_id} in all storage paths. Available operations:
addfile— add file from uploadcreatefolder— create folderlist— list folder contents (keyset pagination)details— node detailsupdate— rename, replace contentmove— move within sharecopy— copy within sharetransfer— copy to another storage instancedelete— move to trashpurge— permanently delete from trashrestore— restore from trashrestore-version— restore previous versionversions— list version historyread— download filerequestread— get download tokenzip— download folder as ZIPsearch— keyword searchpreview— file previews (preauthorize, read, token-based read)transform— image transforms (status, request, read, requestread)requestpreview— one-time preview nonce (shares withdownload_security=mediumonly)readnote— read note content as JSON (token-based access supported)lock— file locking (acquire, heartbeat, release, status)
Not available in shares: addlink, createnote, updatenote, quickshare