fast-io
Workspaces for agentic teams. Complete agent guide with all 19 consolidated tools using action-based routing — parameters, workflows, ID formats, and constraints. Use this skill when agents need shared workspaces to collaborate with other agents and humans, create branded shares (Send/Receive/Exchange), or query documents using built-in AI. Supports ownership transfer to humans, workspace management, workflow primitives (tasks, worklogs, approvals, todos), and real-time collaboration. Free agent plan with 50 GB storage and 5,000 monthly credits.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-fast-io
Repository
Skill path: skills/dbalve/fast-io
Workspaces for agentic teams. Complete agent guide with all 19 consolidated tools using action-based routing — parameters, workflows, ID formats, and constraints. Use this skill when agents need shared workspaces to collaborate with other agents and humans, create branded shares (Send/Receive/Exchange), or query documents using built-in AI. Supports ownership transfer to humans, workspace management, workflow primitives (tasks, worklogs, approvals, todos), and real-time collaboration. Free agent plan with 50 GB storage and 5,000 monthly credits.
Open repositoryBest for
Primary workflow: Analyze Data & AI.
Technical facets: Full Stack, Data / AI.
Target audience: everyone.
License: Proprietary.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install fast-io into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding fast-io to shared team environments
- Use fast-io for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: fast-io
description: >-
Workspaces for agentic teams. Complete agent guide with all 19 consolidated
tools using action-based routing — parameters, workflows, ID formats, and
constraints. Use this skill when agents need shared workspaces to collaborate
with other agents and humans, create branded shares (Send/Receive/Exchange),
or query documents using built-in AI. Supports ownership transfer to humans,
workspace management, workflow primitives (tasks, worklogs, approvals, todos),
and real-time collaboration.
Free agent plan with 50 GB storage and 5,000 monthly credits.
license: Proprietary
compatibility: >-
Requires network access. Connects to the Fast.io MCP server at mcp.fast.io
via Streamable HTTP (/mcp) or SSE (/sse).
metadata:
author: fast-io
version: "1.121.0"
homepage: "https://fast.io"
---
# Fast.io MCP Server -- AI Agent Guide
**Version:** 1.121
**Last Updated:** 2026-03-06
The definitive guide for AI agents using the Fast.io MCP server. Covers why and how to use the platform: product capabilities, the free agent plan, authentication, core concepts (workspaces, shares, intelligence, previews, comments, URL import, metadata, workflow, ownership transfer), 12 end-to-end workflows, interactive MCP App widgets, and all 19 consolidated tools with action-based routing.
> **Versioned guide.** This guide is versioned and updated with each server release. The version number at the top of this document tracks tool parameters, ID formats, and API behavior changes. If you encounter unexpected errors, the guide version may have changed since you last read it.
> **Platform reference.** For a comprehensive overview of Fast.io's capabilities, the agent plan, key workflows, and upgrade paths, see [references/REFERENCE.md](references/REFERENCE.md).
---
## 1. Overview
**Workspaces for Agentic Teams. Collaborate, share, and query with AI -- all through one API, free.**
Fast.io provides workspaces for agentic teams -- where agents collaborate with other agents and with humans. Upload outputs, create branded data rooms, ask questions about documents using built-in AI, and hand everything off to a human when the job is done. No infrastructure to manage, no subscriptions to set up, no credit card required.
### The Problem Fast.io Solves
Agentic teams -- groups of agents working together and with humans -- need a shared place to work. Today, agents cobble together S3 buckets, presigned URLs, email attachments, and custom download pages. Every agent reinvents collaboration, and there is no shared workspace where agents and humans can see the same files, track activity, and hand off work.
When agents need to *understand* documents -- not just store them -- they have to download files, parse dozens of formats, build search indexes, and manage their own RAG pipeline. That is a lot of infrastructure for what should be a simple question: "What does this document say?"
| Problem | Fast.io Solution |
|---------|-----------------|
| No shared workspace for agentic teams | Workspaces where agents and humans collaborate with file preview, versioning, and AI |
| Agent-to-agent coordination lacks structure | Shared workspaces with activity feeds, comments, and real-time sync across team members |
| Sharing outputs with humans is awkward | Purpose-built shares (Send, Receive, Exchange) with link sharing, passwords, expiration |
| Collecting files from humans is harder | Receive shares let humans upload directly to your workspace -- no email attachments |
| Understanding document contents | Built-in AI reads, summarizes, and answers questions about your files |
| Building a RAG pipeline from scratch | Enable intelligence on a workspace and documents are automatically indexed, summarized, and queryable |
| Finding the right file in a large collection | Semantic search finds documents by meaning, not just filename |
| Handing a project off to a human | One-click ownership transfer -- human gets the org, agent keeps admin access |
| Tracking what happened | Full audit trail with AI-powered activity summaries |
| Cost | Free. 50 GB storage, 5,000 monthly credits, no credit card |
### MCP Server
This MCP server exposes 19 consolidated tools that cover the full Fast.io REST API surface. Every authenticated API endpoint has a corresponding tool action, and the server handles session management automatically.
Once a user authenticates, the auth token is stored in the server session and automatically attached to all subsequent API calls. There is no need to pass tokens between tool invocations.
### Server Endpoints
- **Production:** `mcp.fast.io`
- **Development:** `mcp.fastdev1.com`
Two transports are available on each:
- **Streamable HTTP at `/mcp`** -- the preferred transport for new integrations.
- **SSE at `/sse`** -- a legacy transport maintained for backward compatibility.
### MCP Resources
The server exposes static MCP resources, widget resources, and file download resource templates. Clients can read them via `resources/list` and `resources/read`:
| URI | Name | Description | MIME Type |
|-----|------|-------------|-----------|
| `skill://guide` | skill-guide | Full agent guide (this document) with all 19 tools, workflows, and platform documentation | `text/markdown` |
| `session://status` | session-status | Current authentication state: `authenticated` boolean, `user_id`, `user_email`, `token_expires_at` (Unix epoch), `token_expires_at_iso` (ISO 8601), `scopes` (raw scope string or null), `scopes_detail` (array of hydrated scope objects with entity names/domains/parents, or null), `agent_name` (string or null) | `application/json` |
| `widget://*` | Widget HTML | Interactive HTML5 widgets (6 total) -- use the `apps` tool to discover and launch | `text/html` |
**File download resource templates** -- read file content directly through MCP without needing external HTTP access:
| URI Template | Name | Auth | Dynamic Listing | Description |
|---|---|---|---|---|
| `download://workspace/{workspace_id}/{node_id}` | download-workspace-file | Session token | Yes | Download a file from a workspace |
| `download://share/{share_id}/{node_id}` | download-share-file | Session token | Yes | Download a file from a share |
| `download://quickshare/{quickshare_id}` | download-quickshare-file | None (public) | No | Download a quickshare file |
Files up to 50 MB are returned inline as base64-encoded blob content. Larger files return a text fallback with a URL to the HTTP pass-through endpoint (see below). The `download` tool responses include a `resource_uri` field with the appropriate URI for each file.
**Dynamic resource listing:** When authenticated, workspace and share file resources are dynamically listed via `resources/list`. MCP clients (such as Claude Desktop's `@` mention picker) can discover available files without any tool calls. Up to 10 workspaces and 10 shares are enumerated, with up to 25 most recently updated root-level files from each. Resources appear as "WorkspaceName / filename.ext" or "ShareTitle / filename.ext". Results are cached for 1 minute per session. Only root-level files are listed -- subdirectories are not recursively enumerated. Use the `storage` tool with action `list` to browse deeper. The quickshare template remains template-only and is not dynamically enumerable.
### MCP Prompts
The server registers MCP prompts that appear in the client's "Add From" / "+" menu as user-clickable app launchers. These are primarily for desktop MCP clients (e.g., Claude Desktop); code-mode clients (Claude Code, Cursor) do not surface prompts.
| Prompt Name | Description |
|---|---|
| `App: Choose Workspace or Org` | Launch the Workspace Picker to browse orgs, select workspaces, and manage shares |
| `App: Pick a File` | Launch the File Picker with built-in workspace navigator for browsing, searching, and selecting files |
| `App: Open Workflow` | Launch the Workflow Manager (auto-selects workspace if only one, otherwise opens Workspace Picker first) |
| `App: Upload Files` | Launch the Uploader to upload files with drag-and-drop, progress tracking, and text file creation |
| `App: Available Apps` | List all available MCP App widgets with descriptions and launch instructions |
### HTTP File Pass-Through
For files larger than 50 MB or when raw binary streaming is needed, the server provides an HTTP pass-through endpoint that streams file content directly from the API:
| Endpoint | Auth | Description |
|---|---|---|
| `GET /file/workspace/{workspace_id}/{node_id}` | `Mcp-Session-Id` header | Stream a workspace file |
| `GET /file/share/{share_id}/{node_id}` | `Mcp-Session-Id` header | Stream a share file |
| `GET /file/quickshare/{quickshare_id}` | None (public) | Stream a quickshare file |
The response includes proper `Content-Type`, `Content-Length`, and `Content-Disposition` headers from the upstream API. Errors are returned as HTML pages. The `Mcp-Session-Id` header is the same session identifier used for MCP protocol communication.
### Workflow Overview
The server includes workflow features for project tracking: **tasks** (structured work items with priorities and assignees), **worklogs** (append-only activity logs), **approvals** (formal sign-off requests), and **todos** (simple checklists). Enable workflow on a workspace with `workspace` action `enable-workflow` before using these tools. See the **Full Agent Workflow** recipe in section 6 for the complete pattern.
**Best practice (IMPORTANT):** After state-changing actions (uploading files, creating shares, changing task status, member changes, file moves/deletes), append a worklog entry describing what you did and why. Without worklog entries, agent work is invisible to humans reviewing the workspace. For multiple related actions (e.g., uploading several files), you may log once after the batch completes rather than after each individual action. Worklog entries are append-only and permanent.
### Additional References
- **Agent guide (this file):** `/skill.md` on the MCP server -- tool documentation, workflows, and constraints.
- **REST API reference:** `https://api.fast.io/llms.txt` -- endpoint documentation for the underlying Fast.io API.
- **Platform guide:** [references/REFERENCE.md](references/REFERENCE.md) -- capabilities, agent plan details, key workflows, and upgrade paths.
---
## 2. Authentication (Critical First Step)
Authentication is required before calling any tool except these unauthenticated tools:
- `auth` with actions: `signin`, `signup`, `set-api-key`, `pkce-login`, `email-check`, `password-reset-request`, `password-reset`
- `download` with action: `quickshare-details`
### Choosing the Right Approach
There are three ways to use Fast.io as an agent, depending on whether you are operating autonomously or assisting an existing human user.
**Option 1: Autonomous Agent -- Create an Agent Account**
If you are operating independently (storing files, running workflows, building workspaces for users), create your own agent account with `auth` action `signup`. Agent accounts get the free agent plan (50 GB, 5,000 monthly credits) and can transfer orgs to humans when ready. This is the recommended path for autonomous agents. See **Agent Account Creation** below for steps.
**Option 2: Assisting a Human -- Use Their API Key**
If a human already has a Fast.io account and wants your help managing their files, workspaces, or shares, they can create an API key for you to use. No separate agent account is needed -- you operate as the human user. The human creates a key at Settings -> Devices & Agents -> API Keys (direct link: `https://go.fast.io/settings/api-keys`). Call `auth` with action `set-api-key` and the key to authenticate -- the key is validated and stored in the session automatically. API keys work as Bearer tokens and by default have the same permissions as the account owner. Keys can optionally be scoped to specific organizations, workspaces, or shares (using the same scope system as OAuth tokens), tagged with an `agent_name` for tracking, and given an expiration date. Unscoped keys do not expire unless revoked. Agents can also manage API keys programmatically with `auth` actions `api-key-create`, `api-key-update`, `api-key-list`, `api-key-get`, and `api-key-delete`.
**Option 3: Agent Account Invited to a Human's Org**
If you want your own agent identity but need to work within a human's existing organization, create an agent account with `auth` action `signup`, then have the human invite you to their org with `member` action `add` (entity_type `org`) or to a workspace with `member` action `add` (entity_type `workspace`). Alternatively the human can invite via the UI: Settings -> Your Organization -> Manage People. This gives you access to their workspaces and shares while keeping your own account separate. After accepting invitations with `user` action `accept-all-invitations`, use `auth` action `signin` to authenticate normally. **Note:** If the human only invites you to a workspace (not the org), the org will appear as external -- see **Internal vs External Orgs** in the Organizations section.
**Option 4: Browser Login (PKCE)**
If you prefer not to send a password through the agent, use browser-based PKCE login. Call `auth` action `pkce-login` (optionally with an `email` hint) to get a login URL. The user opens the URL in a browser, signs in (email/password or SSO like Google/Microsoft), and approves access. The browser displays an authorization code which the user copies back to the agent. Call `auth` action `pkce-complete` with the code to finish signing in. This is the most secure option -- no credentials pass through the agent.
PKCE login supports optional **scoped access** via the `scope_type` parameter. By default, `scope_type` is `"user"` (full account access). Other scope types restrict the token to specific entity types:
| scope_type | Access granted |
|------------|---------------|
| `user` | Full account access (default) |
| `org` | User selects specific organizations |
| `workspace` | User selects specific workspaces |
| `all_orgs` | All organizations the user belongs to |
| `all_workspaces` | All workspaces the user has access to |
| `all_shares` | All shares the user is a member of (`share:*:<mode>`) |
**Scope inheritance:** Broader scopes include access to child entities automatically:
- `all_orgs` includes all orgs + all workspaces + all shares within those orgs
- `all_workspaces` includes all workspaces + all shares within those workspaces
- `org` scope on a specific org includes access to all workspaces and shares within that org
- `workspace` scope on a specific workspace includes access to shares within that workspace
- `all_shares` grants direct access to all shares the user has membership in, bypassing workspace/org inheritance
The `agent_name` parameter controls what the user sees on the approval screen -- the screen displays "**[agent_name]** will act on your behalf". If omitted, only the client name is shown. Use a descriptive name so the user knows which agent is requesting access.
**Approval flow by scope_type:**
- **`user`** (default): Full account access. The user sees a simple approve/decline prompt with no entity picker.
- **`org`**, **`workspace`**: The user sees an entity selection screen listing their accessible entities with checkboxes, plus a read-only / read-write toggle. The user picks which entities to grant, then approves or declines.
- **`all_orgs`**, **`all_workspaces`**, **`all_shares`**: The user sees a summary of the wildcard access being requested (no entity picker), then approves or declines.
The MCP server defaults to `scope_type="user"` for backward compatibility.
| Scenario | Recommended Approach |
|----------|---------------------|
| Operating autonomously, storing files, building for users | Create an agent account with your own org (Option 1) |
| Helping a human manage their existing account | Ask the human to create an API key for you (Option 2) |
| Working within a human's org with your own identity | Create an agent account, have the human invite you (Option 3) |
| Building something to hand off to a human | Create an agent account, build it, then transfer the org (Option 1) |
| Signing in without sending a password through the agent | Browser-based PKCE login (Option 4) |
**Credit limits by account type:** Agent accounts (Options 1, 3) can transfer orgs to humans when credits run out -- see Ownership Transfer in section 3. Human accounts (Option 2) cannot use the transfer/claim API; direct the human to upgrade their plan at `https://go.fast.io/settings/billing` or via `org` action `billing-create`.
### Standard Sign-In Flow
1. Call `auth` with action `signin`, `email` and `password`.
2. The server returns a JWT `auth_token` and stores it in the session automatically.
3. All subsequent tool calls use this token without any manual passing.
### Agent Account Creation
When creating a new account (Options 1 and 3 above), agents **MUST** use `auth` action `signup` which automatically registers with `agent=true`. Never sign up as a human account. Agent accounts provide:
- `account_type` set to `"agent"`
- Free agent plan assigned automatically
- Transfer/claim workflow enabled for handing orgs off to humans
**Steps:**
1. Optionally call `auth` action `email-check` with the desired `email` to verify it is available for registration before attempting signup.
2. Call `auth` action `signup` with `first_name`, `last_name`, `email`, and `password`. The `agent=true` flag is sent automatically by the MCP server.
3. The account is created and a session is established automatically -- the agent is signed in immediately.
4. **Verify your email** (required before using most endpoints): Call `auth` action `email-verify` with `email` to send a verification code, then call `auth` action `email-verify` again with `email` and `email_token` to validate the code.
5. No credit card is required. No trial period. No expiration. The account persists indefinitely.
### Two-Factor Authentication Flow
1. Call `auth` action `signin` with `email` and `password`.
2. If the response includes `two_factor_required: true`, the returned token has limited scope.
3. Call `auth` action `2fa-verify` with the 2FA `code` (TOTP, SMS, or WhatsApp).
4. The server replaces the limited-scope token with a full-scope token automatically.
### Inline 2FA for Sensitive Operations
Some API endpoints require per-request 2FA verification when the account has 2FA enabled. These operations require a valid 2FA `token` parameter (6-digit TOTP or SMS/call/WhatsApp code) in addition to normal authentication:
- **`api-key-create`** — creating a new API key
- **`api-key-delete`** — revoking an API key
If the account does not have 2FA enabled, these operations work normally without a token. If 2FA is enabled and the token is missing or invalid, the request fails.
**Workflow:**
1. Check 2FA status: `auth` action `2fa-status` — if `state` is `"enabled"`, inline 2FA is required.
2. Prompt the user for a TOTP code from their authenticator app, or send a code via `auth` action `2fa-send`.
3. Pass the code as the `token` parameter to `api-key-create` or `api-key-delete`.
**Tip:** API key authentication (`auth` action `set-api-key`) bypasses inline 2FA checks entirely. If the agent is already authenticated via API key, no token is needed for these operations.
### Browser Login (PKCE) Flow
1. Call `auth` action `pkce-login` (optionally with `email` to pre-fill the sign-in form, `scope_type` to request scoped access, and `agent_name` to identify the agent).
2. The tool returns a `login_url` -- present it to the user to open in a browser.
3. The user signs in (email/password or SSO).
4. The user sees the approval screen showing the `agent_name` (or client name if not provided). Depending on `scope_type`: for `user` they simply approve; for `org`/`workspace` they select specific entities and read-only/read-write access; for `all_orgs`/`all_workspaces`/`all_shares` they review the wildcard access summary.
5. The user clicks Approve. The browser displays an authorization code. The user copies it.
6. Call `auth` action `pkce-complete` with the `code` to exchange it for an access token.
7. The session is established automatically -- all subsequent tool calls are authenticated. If scoped access was granted, `scopes` and `agent_name` are included in the response and stored in the session.
### Checking Session Status
- `auth` action `status` -- checks the local Durable Object session. No API call is made. Returns authentication state, user ID, email, token expiry, scopes, and agent_name.
- `auth` action `check` -- validates the token against the Fast.io API. Returns the user ID if the token is still valid.
### Session Expiry
JWT tokens last **1 hour**. API keys do not expire by default, but can optionally have an expiration set via `api-key-create` or `api-key-update` with the `key_expires` parameter. When a JWT session expires or a time-limited API key expires, tool calls return a clear error indicating that re-authentication is needed. Call `auth` action `signin` again to establish a new session. The MCP server does not auto-refresh tokens.
**Tip:** For long-running sessions, use `auth` action `status` to check remaining token lifetime before starting a multi-step workflow. If the token is close to expiring, re-authenticate first to avoid mid-workflow interruptions.
### Signing Out
Call `auth` action `signout` to clear the stored session from the Durable Object.
---
## 3. Core Concepts
### Organizations
Organizations are top-level containers that collect workspaces. An organization can represent a company, a business unit, a team, or simply your own personal collection. Every user belongs to one or more organizations. Organizations have:
- **Workspaces** — the file storage containers that belong to the organization.
- **Members** with roles: owner, admin, member, guest, view.
- **Billing and subscriptions** managed through Stripe integration.
- **Plan limits** that govern storage, transfer, AI tokens, and member counts.
Organizations are identified by a 19-digit numeric profile ID or a domain string.
**IMPORTANT:** When creating orgs, agents MUST use `org` action `create` which automatically assigns `billing_plan: "agent"`. This ensures the org gets the free agent plan (50 GB, 5,000 credits/month). Do not use any other billing plan for agent-created organizations.
#### Org Discovery (IMPORTANT)
To discover all available orgs, agents **must call both actions**:
1. `org` action `list` -- returns internal orgs where you are a direct member (`member: true`)
2. `org` action `discover-external` -- returns external orgs you access via workspace membership only (`member: false`)
**An agent that only checks `org` action `list` will miss external orgs entirely and won't discover the workspaces it's been invited to.** External orgs are the most common pattern when a human invites an agent to help with a specific project -- they add the agent to a workspace but not to the org itself.
#### Internal vs External Orgs
**Internal orgs** (`member: true`) -- orgs you created or were invited to join as a member. You have org-level access: you can see all workspaces (subject to permissions), manage settings if you're an admin, and appear in the org's member list.
**External orgs** (`member: false`) -- orgs you can access only through workspace membership. You can see the org's name and basic public info, but you cannot manage org settings, see other workspaces, or add members at the org level. Your access is limited to the specific workspaces you were explicitly invited to.
**Example:** A human invites your agent to their "Q4 Reports" workspace. You can upload files, run AI queries, and collaborate in that workspace. But you cannot create new workspaces in their org, view their billing, or access their other workspaces. The org shows up via `org` action `discover-external` -- not `org` action `list`. If the human later invites you to the org itself, the org moves from external to internal.
### Workspaces
Workspaces are file storage containers within organizations. Each workspace has:
- Its own set of **members** with roles (owner, admin, member, guest).
- A **storage tree** of files and folders (storage nodes).
- Optional **AI features** for RAG-powered chat.
- **Shares** that can be created within the workspace.
- **Archive/unarchive** lifecycle management.
- **50 GB included storage** on the free agent plan, with files up to 1 GB per upload.
- **File versioning** -- every edit creates a new version, old versions are recoverable.
- **Full-text and semantic search** -- find files by name or content, and documents by meaning.
Workspaces are identified by a 19-digit numeric profile ID.
#### Intelligence: On or Off
Workspaces have an **intelligence** toggle that controls whether AI features are active.
> **⚠️ COST WARNING:** Intelligence incurs significant ingestion costs (10 credits per page for every uploaded document). For a workspace with hundreds or thousands of pages, this adds up quickly. **Do NOT enable intelligence unless the user specifically needs RAG queries across many documents or AI-powered semantic search.** Most workflows (file storage, sharing, collaboration, one-off file analysis) work perfectly without it.
**Intelligence OFF (recommended default)** -- the workspace is pure file storage. You can still attach files directly to an AI chat conversation (up to 20 files, 200 MB total) and ask questions about them -- no ingestion cost. This is the right choice for most use cases: file storage, sharing, collaboration, project coordination, and analyzing a small number of specific files.
**Intelligence ON (only when needed)** -- the workspace becomes an AI-powered knowledge base. Every document and code file uploaded is automatically ingested, summarized, and indexed. **Only enable this when the user needs one of these two capabilities:**
1. **RAG queries across many documents** -- scope AI chat to entire folders or the full workspace and ask questions across all indexed content. The AI retrieves relevant passages and answers with citations. This is useful when you have a large volume of documents and need to search across all of them.
2. **AI-powered semantic search** -- find files by meaning, not just keywords. "Show me contracts with indemnity clauses" works even if those exact words do not appear in the filename.
Intelligence also enables auto-summarization and automatic metadata extraction, but these alone do not justify the ingestion cost.
> **Coming soon:** RAG indexing support for images, video, and audio files. Currently only documents and code are indexed.
**Default behavior:** Intelligence defaults to ON for workspaces created via the API by agent accounts. **You should explicitly set `intelligence` to `"false"` when creating workspaces unless the user has asked for RAG or AI search capabilities.** Do not enable it speculatively "just in case" -- it can always be enabled later, but ingestion costs are incurred immediately and are non-refundable.
**Agent use case:** Create a workspace per project or client. Keep intelligence OFF for storage and collaboration. Only enable it when users need to query across a large document set. Upload reports, datasets, and deliverables. Invite other agents and human stakeholders. Everything is organized, searchable, and versioned.
For full details on AI chat types, file context modes, AI state, and how intelligence affects them, see the **AI Chat** section below.
### Shares
Shares are purpose-built spaces for exchanging files with people outside your workspace. They can exist within workspaces and have three types:
| Mode | What It Does | Agent Use Case |
|------|-------------|----------------|
| **Send** | Recipients can download files | Deliver reports, exports, generated content |
| **Receive** | Recipients can upload files | Collect documents, datasets, user submissions |
| **Exchange** | Both upload and download | Collaborative workflows, review cycles |
#### Share Features
- **Password protection** -- require a password for link access
- **Expiration dates** -- shares auto-expire after a set period
- **Download controls** -- enable or disable file downloads
- **Access levels** -- Members Only, Org Members, Registered Users, or Public (anyone with the link)
- **Custom branding** -- background images, gradient colors, accent colors, logos
- **Post-download messaging** -- show custom messages and links after download
- **Up to 3 custom links** per share for context or calls-to-action
- **Guest chat** -- let share recipients ask questions in real-time
- **AI-powered auto-titling** -- shares automatically generate smart titles from their contents
- **Activity notifications** -- get notified when files are sent or received
- **Comment controls** -- configure who can see and post comments (owners, guests, or both)
#### Two Storage Modes
When creating a share with `share` action `create`, the `storage_mode` parameter determines how files are stored:
- **`room`** (independent storage, default) -- The share has its own isolated storage. Files are added directly to the share and are independent of any workspace. This creates a self-contained data room -- changes to workspace files do not affect the room, and vice versa. Use for final deliverables, compliance packages, archived reports, or any scenario where you want an immutable snapshot.
- **`shared_folder`** (workspace-backed) -- The share is backed by a specific folder in a workspace. The share displays the live contents of that folder -- any files added, updated, or removed in the workspace folder are immediately reflected in the share. No file duplication, so no extra storage cost. To create a shared folder, pass `storage_mode=shared_folder` and `folder_node_id={folder_opaque_id}` when creating the share. **Note:** Expiration dates are not allowed on shared folder shares since the content is live.
Both modes look the same to share recipients -- a branded data room with file preview, download controls, and all share features. The difference is whether the content is a snapshot (room) or a live view (shared folder).
Shares are identified by a 19-digit numeric profile ID.
**Agent use case:** Generate a quarterly report, create a Send share with your client's branding, set a 30-day expiration, and share the link. The client sees a professional, branded page with instant file preview -- not a raw download link.
### Storage Nodes
Files and folders are represented as storage nodes. Each node has an opaque ID (a 30-character alphanumeric string, displayed with hyphens, e.g. `f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4`). The special value `root` refers to the root folder of a workspace or share, and `trash` refers to the trash folder.
Key operations on storage nodes: list, create-folder, move, copy, rename, delete (moves to trash), purge (permanently deletes), restore (recovers from trash), search, add-file (link an upload), and add-link (create a share reference).
Nodes have versions. Each file modification creates a new version. Version history can be listed and files can be restored to previous versions.
**Conflict resolution (REPLACE by default):** When a file operation encounters an existing file with the same name in the target folder, the default behavior is to **replace** (overwrite) the existing file:
- **Upload (addfile)** -- silently overwrites the existing file. The previous content is preserved as a version entry, recoverable via `storage` action `version-list` / `version-restore`.
- **Move / Copy** -- trashes the existing conflicting file, then completes the operation. The old file is recoverable from trash.
- **Restore from trash** -- trashes the existing conflicting file, then restores.
- **Folder conflicts and type mismatches** (file vs folder) still fall back to rename (e.g. `folder (2)`).
This means uploading a file with the same name as an existing file will **overwrite it**, not create a renamed copy like `report (2).pdf`. If you need multiple files with the same name to coexist, rename them before uploading.
### Notes
Notes are a storage node type (alongside files and folders) that store markdown content directly on the server. They live in the same folder hierarchy as files, are versioned like any other node, and appear in storage listings with `type: "note"`.
#### Creating and Updating Notes
Create notes with `workspace` action `create-note`, read with `workspace` action `read-note`, and update with `workspace` action `update-note`.
**Creating:** Provide `workspace_id`, `parent_id` (folder opaque ID or `"root"`), `name` (must end in `.md`, max 100 characters), and `content` (markdown text, max 100 KB).
**Reading:** Provide `workspace_id` and `node_id`. Returns the note's markdown content and metadata.
**Updating:** Provide `workspace_id`, `node_id`, and at least one of `name` (must end in `.md`) or `content` (max 100 KB).
| Constraint | Limit |
|------------|-------|
| Content encoding | Valid UTF-8 (UTF8MB4). Invalid byte sequences and control characters (`\p{C}` except `\t`, `\n`, `\r`) are stripped. |
| Content size | 100 KB max |
| Filename | 1-100 characters, must end in `.md` |
| Markdown validation | Code blocks and emphasis markers must be balanced |
| Rate limit | 2 per 10s, 5 per 60s |
#### Notes as Long-Term Knowledge Grounding
In an intelligent workspace, notes are automatically ingested and indexed just like uploaded documents. This makes notes a way to bank knowledge over time -- any facts, context, or decisions stored in notes become grounding material for future AI queries.
When an AI chat uses folder scope (or defaults to the entire workspace), notes within that scope are searched alongside files. The AI retrieves relevant passages from notes and cites them in answers.
Key behaviors:
- Notes are ingested for RAG when workspace intelligence is enabled
- Notes within a folder scope are included in scoped queries
- Notes with `ai_state: ready` are searchable via RAG
- Notes can also be attached directly to a chat via `files_attach` (check `ai.attach` is `true` in storage details)
**Use cases:**
- Store project context, decisions, and rationale. Months later, ask "Why did we choose vendor X?" and the AI retrieves the note.
- Save research findings in a note. Future AI chats automatically use those findings as grounding.
- Create reference documents (style guides, naming conventions) that inform all future AI queries in the workspace.
#### Other Note Operations
Notes support the same storage operations as files and folders: move (via `storage` action `move`), copy (`storage` action `copy`), delete/trash (`storage` action `delete`), restore (`storage` action `restore`), version history (`storage` action `version-list`), and details (`storage` action `details`).
#### Linking Users to Notes
- **Note in workspace context** (opens workspace with note panel): `https://{domain}.fast.io/workspace/{folder_name}/storage/root?note={note_id}`
- **Note preview** (standalone view): `https://{domain}.fast.io/workspace/{folder_name}/preview/{note_id}`
### AI Chat
AI chat lets agents ask questions about files stored in workspaces and shares. Two chat types are available, each with different file context options.
**AI chat is read-only.** It can read, analyze, search, and answer questions about file contents, but it cannot modify files, change workspace settings, manage members, or access events. Any action beyond reading file content — uploading, deleting, moving files, changing settings, managing shares, reading events — must be done through the MCP tools directly. Do not attempt to use AI chat as a general-purpose tool for workspace management.
#### Two Chat Types
- **`chat`** — Basic AI conversation with no file context from the workspace index. Use for general questions only.
- **`chat_with_files`** — AI grounded in your files. Two mutually exclusive modes for providing file context:
- **Folder/file scope (RAG)** — limits the retrieval search space. Requires intelligence enabled; files must be in `ready` AI state.
- **File attachments** — files read directly by the AI. No intelligence required; files must have `ai.attach: true` in storage details (the file must be a supported type for AI analysis). Max 20 files, 200 MB total.
**Auto-promotion:** If you create a chat with `type=chat` but include `files_scope`, `folders_scope`, or `files_attach`, the system automatically promotes the type to `chat_with_files`. You don't need to worry about setting the type exactly right — the intent is unambiguous when file parameters are present.
Both types augment answers with web knowledge when relevant.
#### File Context: Scope vs Attachments
For `chat_with_files`, choose one of these mutually exclusive approaches:
| Feature | Folder/File Scope (RAG) | File Attachments |
|---------|------------------------|------------------|
| How it works | Limits RAG search space | Files read directly by AI |
| Requires intelligence | Yes | No |
| File readiness requirement | `ai_state: ready` | `ai.attach: true` |
| Best for | Many files, knowledge retrieval | Specific files, direct analysis |
| Max references | 100 folder refs (subfolder tree expansion) or 100 file refs | 20 files / 200 MB |
| Default (no scope given) | Entire workspace | N/A |
**Scope parameters** (REQUIRES intelligence — will error if intelligence is off):
- `folders_scope` — comma-separated `nodeId:depth` pairs (depth 1-10, max 100 subfolder refs). Defines a search boundary — the RAG backend finds documents within scoped folders automatically. Just pass folder IDs with depth; do not enumerate individual files. A folder with thousands of files and few subfolders works fine.
- `files_scope` — comma-separated `nodeId:versionId` pairs (max 100). Limits RAG to specific indexed files. nodeId is required; versionId is required in the pair format but will be **auto-resolved to the node's current version** if left empty (e.g., `nodeId:` with nothing after the colon). Get `versionId` from the file's `version` field in `storage` action `list` or `details` responses.
- **If neither is specified, the default scope is the entire workspace (all indexed documents).** This is the recommended default — omit scope parameters unless you specifically need to narrow the search.
**Attachment parameter** (no intelligence required):
- `files_attach` — comma-separated `nodeId:versionId` pairs (max 20, 200 MB total). nodeId is required; versionId will be **auto-resolved to the current version** if left empty. Files are read directly, not via RAG. **FILES ONLY: passing a folder nodeId returns a 406 error.** To include folder contents in AI context, use `folders_scope` instead (requires intelligence). **Only files with `ai.attach: true` in storage details can be attached** — check before using.
**Do not** list folder contents and pass individual file IDs as `files_scope` when you mean to search a folder — use `folders_scope` with the folder's nodeId instead. `files_scope` is only for targeting specific known file versions.
**Scope vs attach:** `files_scope` and `folders_scope` narrow the RAG search boundary and **require workspace intelligence to be enabled** — they will error on non-intelligent workspaces. `files_attach` sends files directly to the AI without indexing and works regardless of intelligence setting, but accepts only file nodeIds (not folders).
`files_scope`/`folders_scope` and `files_attach` are mutually exclusive — sending both will error.
#### Intelligence and AI State
The workspace intelligence toggle (see Workspaces above) controls whether uploaded documents and code files are auto-ingested, summarized, and indexed for RAG. When intelligence is enabled, each file has an `ai_state` indicating its readiness:
| State | Meaning |
|-------|---------|
| `disabled` | AI processing disabled for this file |
| `pending` | Queued for processing |
| `in_progress` | Currently being ingested and indexed |
| `ready` | Complete — available for folder/file scope queries |
| `failed` | Processing failed |
Only files with `ai_state: ready` are included in folder/file scope searches. Check file state via `storage` action `details` with `context_type: "workspace"`.
#### Attachability — the `ai.attach` Flag
File nodes in storage list/details responses include an `ai` object with three fields:
| Field | Type | Meaning |
|-------|------|---------|
| `ai.state` | string | AI indexing state (`disabled`, `pending`, `inprogress`, `ready`, `failed`) |
| `ai.attach` | boolean | Whether the file can be used with `files_attach` |
| `ai.summary` | boolean | Whether the file already has an AI-generated summary |
**Before using `files_attach`, check that `ai.attach` is `true`.** A file is attachable when its type supports AI analysis (documents, code, images, PDFs, spreadsheets, etc.) or when it already has a summary from prior processing. Files with `ai.attach: false` (unsupported formats, corrupt files, or files still processing) will be rejected by the API.
This flag is independent of the workspace intelligence setting — a file can have `ai.attach: true` even when intelligence is off.
**When to enable intelligence:** You need RAG queries across many documents (scoped to folders or the full workspace) or AI-powered semantic search. Do NOT enable just for auto-summarization or metadata extraction alone -- the ingestion cost (10 credits/page) is significant.
**When to disable intelligence (recommended default):** The workspace is for storage, sharing, collaboration, or you only need to analyze specific files via attachments. This covers most use cases. Saves significant credits. Intelligence can always be enabled later if needed.
Even with intelligence off, `chat_with_files` with file attachments still works for files with `ai.attach: true`.
#### How to Phrase Questions
**With folder/file scope (RAG):** Write questions likely to match content in indexed files. The AI searches the scope, retrieves passages, and cites them.
- Good: "What are the payment terms in the vendor contracts?"
- Good: "Summarize the key findings from the Q3 analysis reports"
- Bad: "Tell me about these files" — too vague, no specific content to match
- Bad: "What's in this workspace?" — cannot meaningfully search for "everything"
**With file attachments:** Be direct — the AI reads the full file content. No retrieval step.
- "Describe this image in detail"
- "Extract all dates and amounts from this invoice"
- "Convert this CSV data into a summary table"
**Personality:** The `personality` parameter controls the tone and length of AI responses. Pass it when creating a chat or sending a message:
- `concise` — short, brief answers
- `detailed` — comprehensive answers with context and evidence (default)
Use `concise` when you need a quick fact, a yes/no answer, or a brief summary. Use `detailed` (or omit the parameter) when you need thorough analysis with supporting evidence and citations. The personality can also be overridden per follow-up message.
**Controlling verbosity in questions:** You can also guide verbosity through how you phrase the question itself:
- "In one sentence, what is the main conclusion of this report?"
- "List only the file names that mention GDPR compliance, no explanations"
- "Give me a brief summary — 2-3 bullet points max"
Combining `personality: "concise"` with a direct question produces the shortest answers and uses the fewest AI credits.
#### Chat Parameters
Create a chat with `ai` action `chat-create` (with `context_type: "workspace"`) or `ai` action `chat-create` (with `context_type: "share"`):
- `type` (required) — `chat` or `chat_with_files`
- `query_text` (required for workspace, optional for share) — initial message, 2-12,768 characters
- `personality` (optional) — `concise` or `detailed` (default: `detailed`)
- `privacy` (optional) — `private` or `public` (default: `public`)
- `files_scope` (optional) — `nodeId:versionId,...` (max 100, requires `chat_with_files` + intelligence). nodeId required; versionId auto-resolved if empty. **Omit to search all indexed documents (recommended default).**
- `folders_scope` (optional) — `nodeId:depth,...` (depth 1-10, max 100 subfolder refs, requires `chat_with_files` + intelligence). Folder scope = search boundary, not file enumeration. **Omit to search all indexed documents (recommended default).**
- `files_attach` (optional) — `nodeId:versionId,...` (max 20 / 200 MB, nodeId required, versionId auto-resolved if empty, mutually exclusive with scope params)
#### Follow-up Messages
Send follow-ups with `ai` action `message-send` (with `context_type: "workspace"` or `"share"`). The chat type is inherited from the parent chat. Each follow-up can update the scope, attachment, and personality parameters.
#### Waiting for AI Responses
After creating a chat or sending a message, the AI response is asynchronous. Message states progress: `ready` → `in_progress` → `complete` (or `errored`).
**Recommended:** Call `ai` action `message-read` (with `context_type: "workspace"` or `"share"`) with the returned `message_id`. The tool polls automatically (up to 15 attempts, 2-second intervals, ~30 seconds). If the response is still processing after that window, use `event` action `activity-poll` with the workspace/share ID instead of calling the read action in a loop — see Activity Polling in section 7.
#### Response Citations
Completed AI responses include citations pointing to source files:
- `nodeId` — storage node opaque ID
- `versionId` — file version opaque ID
- `entries[].page` — page number
- `entries[].snippet` — text excerpt
- `entries[].timestamp` — audio/video timestamp
#### Linking Users to AI Chats
Append `?chat={chat_opaque_id}` to the workspace storage URL:
`https://{domain}.fast.io/workspace/{folder_name}/storage/root?chat={chat_id}`
#### Share AI Chats
Shares support AI chat with identical capabilities. All workspace AI endpoints have share equivalents accessible via `ai` actions with `context_type: "share"`.
### AI Share / Export
Generate temporary markdown-formatted download URLs for files that can be pasted into external AI tools (ChatGPT, Claude, etc.). Use `ai` action `share-generate` (with `context_type: "workspace"` or `"share"`). URLs expire after 5 minutes. Limits: 25 files maximum, 50 MB per file, 100 MB total.
### Profile IDs
Organizations, workspaces, and shares are all identified by 19-digit numeric profile IDs. These appear throughout the tool parameters as `workspace_id`, `share_id`, `org_id`, `profile_id`, and `member_id`.
Most endpoints also accept custom names as identifiers:
| Profile Type | Numeric ID | Custom Name |
|-------------|-----------|-------------|
| Workspace | 19-digit ID | Folder name (e.g., `my-project`) |
| Share | 19-digit ID | URL name (e.g., `q4-financials`) |
| Organization | 19-digit ID | Domain name (e.g., `acme`) |
| User | 19-digit ID | Email address (e.g., `[email protected]`) |
### QuickShares
QuickShares are temporary public download links for individual files in workspaces (not available for shares). They can be accessed without authentication. Expires in seconds from creation (default 10,800 = 3 hours, max 604,800 = 7 days) or as an ISO 8601 datetime via `expires_at`. Max file size: 1 GB. Each quickshare has an opaque identifier used to retrieve metadata and download the file.
### File Preview
Files uploaded to Fast.io get automatic preview generation. When humans open a share or workspace, they see the content immediately -- no "download and open in another app" friction.
Supported preview formats:
- **Images** -- full-resolution with auto-rotation and zoom
- **Video** -- HLS adaptive streaming (50--60% faster load than raw video)
- **Audio** -- interactive waveform visualization
- **PDF** -- page navigation, zoom, text selection
- **Spreadsheets** -- grid navigation with multi-sheet support
- **Code and text** -- syntax highlighting, markdown rendering
Use `storage` action `preview-url` (with `context_type: "workspace"` or `"share"`) to generate preview URLs. Use `storage` action `preview-transform` (with `context_type: "workspace"` or `"share"`) for image resize, crop, and format conversion.
**Agent use case:** Your generated PDF report does not just appear as a download link. The human sees it rendered inline, can flip through pages, zoom in, and comment on specific sections -- all without leaving the browser.
### Comments and Annotations
Humans and agents can leave feedback directly on files, anchored to specific content using the `reference` parameter:
- **Image comments** -- anchored to spatial regions (normalized x/y/width/height coordinates)
- **Video comments** -- anchored to timestamps with spatial region selection
- **Audio comments** -- anchored to timestamps or time ranges
- **PDF comments** -- anchored to specific pages with optional text snippet selection
- **Text-anchored comments** -- anchored to selected text in markdown/notes using `exact`, `prefix`, `suffix`, `start_offset`, and `end_offset` fields (use `type: "document"` or `type: "text"`)
- **Threaded replies** -- single-level threading only; replies to replies are auto-flattened to the parent
- **Emoji reactions** -- one reaction per user per comment; adding a new reaction replaces the previous one
- **Mention tags** -- reference users and files inline using bracket syntax: `@[profile:id]`, `@[user:opaqueId:Display Name]`, `@[file:fileId:filename.ext]`. Get IDs from member lists, user details, or storage listings. The display name segment is optional for profile tags but recommended for user and file tags
Comments use JSON request bodies (`Content-Type: application/json`), unlike most other endpoints which use form-encoded data.
**Listing comments:** Use `comment` action `list` for per-file comments and `comment` action `list-all` for all comments across a workspace or share. Both support `sort`, `limit` (2-200), `offset`, `include_deleted`, `reference_type` filter, and `include_total`.
**Adding comments:** Use `comment` action `add` with `profile_type`, `profile_id`, `node_id`, and `text`. Optionally include `parent_comment_id` for replies and `reference` to anchor to a specific position. Supports mention tags in the body. Two character limits apply: total body including tags max 8,192 chars, display text (body with `@[...]` tags stripped) max 2,048 chars. Optionally include `linked_entity_type` and `linked_entity_id` to link the comment to a task or approval at creation time.
**Deleting comments:** `comment` action `delete` is recursive -- deleting a parent also removes all replies. `comment` action `bulk-delete` is NOT recursive -- replies to deleted comments are preserved.
**Comment Linking:** Comments can be linked to workflow entities (tasks or approvals). Each comment supports one link at a time (nullable). Use `comment` action `link` to associate an existing comment with a task or approval, `comment` action `unlink` to remove the association, and `comment` action `linked` to reverse-lookup all comments linked to a given entity. You can also link at creation time by passing `linked_entity_type` and `linked_entity_id` to the `add` action. Comment responses include `linked_entity_type` and `linked_entity_id` fields (null when unlinked).
**Linking users to comments:** The preview URL opens the comments sidebar automatically. Deep link query parameters let you target a specific comment or position:
| Parameter | Format | Purpose |
|-----------|--------|---------|
| `?comment={id}` | Comment opaque ID | Scrolls to and highlights a specific comment for 2 seconds |
| `?t={seconds}` | e.g. `?t=45.5` | Seeks to timestamp for audio/video comments |
| `?p={pageNum}` | e.g. `?p=3` | Navigates to page for PDF comments |
Workspace: `https://{org.domain}.fast.io/workspace/{folder_name}/preview/{file_opaque_id}?comment={comment_id}`
Share: `https://go.fast.io/shared/{custom_name}/{title-slug}/preview/{file_opaque_id}?comment={comment_id}`
Parameters can be combined -- e.g. `?comment={id}&t=45.5` to deep link to a video comment at a specific timestamp. In shares, the comments sidebar only opens if the share has comments enabled.
**Agent use case:** You generate a design mockup. The human comments "Change the header color" on a specific region of the image. You read the comment, see exactly what region they are referring to via the `reference.region` coordinates, and regenerate.
**Text-anchored comments (markdown/notes):** To anchor a comment to specific text in a markdown or notes file, use the `reference` parameter with `type: "document"` (or `"text"`, which is an alias) and the text selection fields:
- `exact` (string, max 500 chars) -- the selected text verbatim
- `prefix` (string, max 100 chars) -- ~30-50 characters of context before the selection for disambiguation
- `suffix` (string, max 100 chars) -- ~30-50 characters of context after the selection for disambiguation
- `start_offset` (integer) -- character offset from document start (hint for resolving ambiguous matches)
- `end_offset` (integer) -- character offset for end of selection (hint for resolving ambiguous matches)
At minimum, provide `exact`. The `prefix`/`suffix` fields help locate the selection when the same text appears multiple times. The `start_offset`/`end_offset` fields are optional hints that may not survive document edits.
Example -- text-anchored comment on a markdown file:
```json
{
"action": "add",
"profile_type": "workspace",
"profile_id": "1234567890123456789",
"node_id": "abc123-def456-ghi789",
"text": "This section needs a citation",
"reference": {
"type": "document",
"exact": "Studies show a 40% improvement",
"prefix": "In the results section, ",
"suffix": " compared to the baseline.",
"start_offset": 1250,
"end_offset": 1280
}
}
```
### URL Import
Agents can import files directly from URLs without downloading them locally first. Fast.io's server fetches the file, processes it, and adds it to your workspace or share.
- Supports any HTTP/HTTPS URL
- Supports OAuth-protected sources: **Google Drive, OneDrive, Dropbox**
- Files go through the same processing pipeline (preview generation, AI indexing if intelligence is enabled, virus scanning)
Use `upload` action `web-import` with the source URL, target profile, and parent node ID. Use `upload` action `web-status` to check progress and `upload` action `web-list` to list active import jobs.
**Agent use case:** A user says "Add this Google Doc to the project." You call `upload` action `web-import` with the URL. Fast.io downloads it server-side, generates previews, indexes it for AI, and it appears in the workspace. No local I/O.
### Metadata
Metadata enables structured data annotation on files within workspaces. The system uses a template-based approach: administrators create templates that define the fields (name, type, constraints), then assign a template to the workspace. Files can then have metadata values set against the template fields.
Key points:
- **One template per workspace** -- each workspace supports at most one assigned metadata template at a time.
- **Template categories** -- legal, financial, business, medical, technical, engineering, insurance, educational, multimedia, hr.
- **Field types** -- string, int, float, bool, json, url, datetime -- each with optional constraints (min, max, default, fixed_list, can_be_null).
- **Two metadata types** -- template metadata conforms to template field definitions; custom metadata is freeform key-value pairs not tied to any template.
- **System templates** -- pre-built templates that are automatically cloned when assigned to a workspace, so customizations do not affect the global definition.
- **AI extraction** -- the `extract` action uses AI to analyze file content and automatically populate metadata fields. Extracted values are flagged with `is_auto: true`. Consumes AI credits.
- **Version history** -- metadata changes are tracked with version snapshots, accessible via the `versions` action.
- **Requires billing feature** -- the organization must have the metadata billing feature enabled.
- **Template IDs** are alphanumeric strings prefixed with `mt_` (e.g. `mt_abc123def456`).
### Ownership Transfer
The primary way agents deliver value: build something, then give it to a human. Also the recommended action when the agent plan runs out of credits and API calls start returning 402 Payment Required -- transfer the org to a human who can upgrade to a paid plan.
**IMPORTANT: Account type restriction.** The transfer/claim workflow (`org` actions `transfer-token-create`, `transfer-token-list`, `transfer-token-delete`, `transfer-claim`) is only available when the agent created an **agent account** (via `auth` action `signup`) and that agent account owns the org. If the agent is signed in with a **human account** (via `auth` action `signin`), the transfer/claim API cannot be used. Human-owned orgs must be upgraded directly by the human through the Fast.io dashboard.
**The flow:**
1. Agent creates an agent account with `auth` action `signup` and an org with `org` action `create`, sets up workspaces with `org` action `create-workspace`, uploads files, configures shares
2. Agent generates a transfer token (valid 72 hours) with `org` action `transfer-token-create`
3. Agent sends the claim URL to the human: `https://go.fast.io/claim?token=<token>`
4. Human clicks the link and claims the org with their account
**When to transfer:**
- The org is ready for human use (workspaces configured, files uploaded, shares set up)
- The agent plan runs out of credits (402 Payment Required) -- transfer so the human can upgrade
- The human explicitly asks to take over the org
**Managing transfer tokens:**
- `org` action `transfer-token-list` -- check for existing pending tokens before creating new ones
- `org` action `transfer-token-delete` -- revoke a token if the transfer is no longer needed
- `org` action `transfer-claim` -- claim an org using a token (used by the receiving human's agent)
**What happens after transfer:**
- Human becomes the owner of the org and all workspaces
- Agent retains admin access (can still manage files and shares)
- Human gets a free plan (credit-based, no trial period)
- Human can upgrade to Pro or Business at any time
**Agent use case:** A user says "Set up a project workspace for my team." You create the org, build out the workspace structure, upload templates, configure shares for client deliverables, invite team members -- then transfer ownership. The human walks into a fully configured platform. You stay on as admin to keep managing things.
**402 Payment Required use case (agent account):** While working, the agent hits credit limits. Call `org` action `transfer-token-create`, send the claim URL to the human, and explain they can upgrade to continue. The agent keeps admin access and resumes work once the human upgrades.
**402 Payment Required use case (human account):** The agent cannot transfer the org. Instead, inform the user that their org has run out of credits and they need to upgrade their billing plan. Direct them to the Fast.io dashboard or use `org` action `billing-create` to update to a paid plan.
### Workflow (Tasks, Worklogs, Approvals, Todos)
Workspaces and shares support an optional workflow layer that adds structured task management, activity logging, approval gates, and simple checklists. Workflow features are controlled by a toggle -- they must be explicitly enabled before use. On shares, workflow access requires admin or named member role -- guests and view-only users cannot access workflow features.
#### Enabling Workflow
- **Workspaces:** `workspace` action `enable-workflow` with `workspace_id`
- **Shares:** `share` action `enable-workflow` with `share_id`
Check whether workflow is enabled via `workspace` action `details` or `share` action `details` -- look for `workflow: true` in the response.
Disabling workflow (`workspace` action `disable-workflow` or `share` action `disable-workflow`) makes all workflow data inaccessible but preserves it. Re-enabling restores access.
#### Task Lists and Tasks
Tasks are organized into lists. Each workspace or share can have multiple task lists, and each list contains individual tasks.
- **Task lists** have a name and optional description. Create with `task` action `create-list`, list with `task` action `list-lists`.
- **Tasks** have a title, description, status, priority, assignee, dependencies, and optional node link. Create with `task` action `create-task`, list with `task` action `list-tasks`.
- **Statuses:** `pending`, `in_progress`, `complete`, `blocked`
- **Priorities:** 0 = none, 1 = low, 2 = medium, 3 = high, 4 = critical
- **Assignees** are profile IDs (workspace or share members). Use `task` action `assign-task` to assign or unassign.
- **Bulk operations:** `task` action `bulk-status` changes status on up to 100 tasks at once.
- **Moving tasks:** `task` action `move-task` moves a task from one list to another within the same profile. Requires the source `list_id`, `task_id`, and `target_task_list_id`. Optionally set `sort_order` to control position in the target list (default: 0).
- **Reordering:** `task` action `reorder-tasks` sets the display order of tasks within a list. `task` action `reorder-lists` sets the display order of task lists within a profile. Pass arrays of IDs in the desired order; the server converts them to `{id, sort_order}` objects for the API.
- **Creator tracking:** Tasks and task lists include a `created_by` field (profile ID of the creator).
- **Markdown output:** Pass `format: "md"` to get human-readable markdown instead of JSON.
#### Worklogs
Worklogs are append-only chronological activity logs scoped to tasks, task lists, storage nodes, or profiles. Entries cannot be edited or deleted after creation.
- **Entries:** Regular log entries appended with `worklog` action `append`. Use for progress updates, decisions, reasoning, and status changes.
- **Interjections:** Priority corrections created with `worklog` action `interject`. Interjections are always urgent and require acknowledgement from other participants.
- **Acknowledgement:** `worklog` action `acknowledge` marks an interjection as seen. `worklog` action `unacknowledged` lists interjections that still need acknowledgement. Entries include an `acknowledgable` boolean -- when `true`, the entry is an unacknowledged interjection that can be acknowledged.
- **Response fields:** Entries include `acknowledged` (boolean), `acknowledgable` (boolean), `updated` (ISO 8601 timestamp), and `created` (ISO 8601 timestamp).
- **Markdown output:** Pass `format: "md"` for human-readable output.
#### Approvals
Formal approval requests scoped to tasks, storage nodes, or worklog entries. Use when a decision requires explicit sign-off.
- **Create:** `approval` action `create` with `profile_id`, `description` (1-5000 chars), `entity_type` ("task", "node", or "worklog_entry"), and optionally `approver_id` (a single profile ID, must be an entity member).
- **Resolve:** `approval` action `resolve` with `resolve_action: "approve"` or `"reject"` and an optional comment. Only designated approvers can resolve.
- **Statuses:** `pending`, `approved`, `rejected`
- **Markdown output:** Pass `format: "md"` for human-readable output.
#### Todos
Simple flat checklists scoped to workspaces and shares. No nesting -- just a list of items that can be checked off.
- **Create:** `todo` action `create` with a title.
- **Toggle:** `todo` action `toggle` flips the done state of a single todo. `todo` action `bulk-toggle` sets done state on up to 100 todos at once.
- **Update/Delete:** `todo` action `update` changes title. `todo` action `delete` soft-deletes a todo.
- **Creator tracking:** Todos include a `created_by` field (profile ID of the creator).
- **Markdown output:** Pass `format: "md"` for human-readable output.
#### Notes as Agent Knowledge Layer
Notes (`type: "note"`) are markdown files stored in workspace storage (see **Notes** above). When combined with workflow features, notes become a knowledge layer:
- **Automatic AI indexing:** When workspace intelligence is enabled, notes are ingested and indexed for RAG just like uploaded files.
- **Link tasks to notes:** Tasks can reference storage nodes, including notes. Create context notes for project background, requirements, or reference material, then create tasks that link to those notes for full context.
- **Worklogs for reasoning:** Use worklog entries to record decisions, progress, and reasoning over time. The chronological log builds a narrative that complements the structured task list.
- **AI can search all context:** With intelligence enabled, AI chat can search across notes, worklogs, task descriptions, and uploaded files -- giving comprehensive answers grounded in the project's full history.
**Recommended pattern:** Create notes for project context and requirements. Create task lists for work phases. Link tasks to relevant notes. Log progress with worklogs. Request approvals for decisions. The AI can then answer questions like "Why did we choose this approach?" by searching across all of these artifacts.
### Permission Parameter Values
Several tools use permission parameters with specific allowed values. Use these exact strings when calling the tools.
#### Organization Creation (`org` action `create`)
| Parameter | Allowed Values | Default |
|-----------|----------------|---------|
| `perm_member_manage` | `Owner only`, `Admin or above`, `Member or above` | `Member or above` |
| `industry` | `unspecified`, `technology`, `healthcare`, `financial`, `education`, `manufacturing`, `construction`, `professional`, `media`, `retail`, `real_estate`, `logistics`, `energy`, `automotive`, `agriculture`, `pharmaceutical`, `legal`, `government`, `non_profit`, `insurance`, `telecommunications`, `research`, `entertainment`, `architecture`, `consulting`, `marketing` | `unspecified` |
| `background_mode` | `stretched`, `fixed` | `stretched` |
#### Workspace Creation (`org` action `create-workspace`) and Update (`workspace` action `update`)
| Parameter | Allowed Values | Default |
|-----------|----------------|---------|
| `perm_join` | `Only Org Owners`, `Admin or above`, `Member or above` | `Member or above` |
| `perm_member_manage` | `Admin or above`, `Member or above` | `Member or above` |
#### Share Creation (`share` action `create`)
| Parameter | Allowed Values | Default |
|-----------|----------------|---------|
| `type` | `send`, `receive`, `exchange` | `exchange` |
| `storage_mode` | `independent`, `workspace_folder` | `independent` |
| `access_options` | `Only members of the Share or Workspace`, `Members of the Share, Workspace or Org`, `Anyone with a registered account`, `Anyone with the link` | `Only members of the Share or Workspace` |
| `invite` | `owners`, `guests` | `owners` |
| `notify` | `never`, `notify_on_file_received`, `notify_on_file_sent_or_received` | `never` |
| `display_type` | `list`, `grid` | `grid` |
| `intelligence` | `true`, `false` | `false` |
| `comments_enabled` | `true`, `false` | `true` |
| `download_enabled` | `true`, `false` | `true` |
| `guest_chat_enabled` | `true`, `false` | `false` |
| `workspace_style` | `true`, `false` | `true` |
| `background_image` | `0`-`128` | `0` |
**Share constraints:**
- Receive and Exchange shares cannot use `Anyone with the link` access -- this option is only available for Send shares.
- Password protection (`password` parameter) is only allowed when `access_options` is `Anyone with the link`.
- Expiration (`expires` parameter in MySQL format `YYYY-MM-DD HH:MM:SS`) is not allowed on `workspace_folder` shares.
- Field length and format constraints for `custom_name`, `title`, and `description` are documented in the **Profile Field Constraints** table below.
- Color parameters (`accent_color`, `background_color1`, `background_color2`) accept JSON strings.
- `create_folder` creates a new workspace folder for the share when used with `storage_mode='workspace_folder'`.
### Profile Field Constraints
All profile fields are validated server-side. Requests that violate these constraints are rejected with a 400 error.
| Entity | Field | API Key | Min | Max | Pattern | Required | Nullable |
|--------|-------|---------|-----|-----|---------|----------|----------|
| Org | domain | `domain` | 2 | 63 | `^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$` | Yes (create) | No |
| Org | name | `name` | 3 | 100 | No control chars | Yes | No |
| Org | description | `description` | 10 | 1000 | No control chars | No | Yes |
| Workspace | folder_name | `folder_name` | 4 | 80 | `^[\p{L}\p{N}-]+$` (letters, digits, hyphens) | Yes (create) | No |
| Workspace | name | `name` | 2 | 100 | No control chars | Yes | No |
| Workspace | description | `description` | 10 | 1000 | No control chars | No | Yes |
| Share | custom_name | `custom_name` | 4 | 80 | `^[\p{L}\p{N}]+$` (letters, digits only) | Yes (create) | No |
| Share | custom_url | `custom_url` | 10 | 100 | — | Yes | Yes |
| Share | title | `title` | 2 | 80 | No control chars | Yes | Yes |
| Share | description | `description` | 10 | 500 | No control chars | No | Yes |
- **"No control chars"** = rejects Unicode control characters (`\p{C}`)
- **Org domain**: lowercase ASCII alphanumeric + hyphens; cannot start/end with hyphen
- **Workspace folder_name**: Unicode letters, digits, and hyphens. **Globally unique** -- not scoped to an org. Recommend `{org_id}-{name}` convention to avoid collisions (auto-applied by `create-workspace` when name is taken)
- **Share custom_name**: Unicode letters and digits only (no hyphens or special chars)
- **Share description** max is 500 (org/workspace is 1000)
---
## 4. Agent Plan -- Free Tier
The agent plan is a free tier designed for AI agents. No credit card, no trial period, no expiration. Enough resources to build and demonstrate value, with room to grow when the org transfers to a human on a paid plan.
### Resource Limits
| Resource | Included |
|----------|----------|
| **Price** | $0 -- no credit card, no trial period, no expiration |
| **Storage** | 50 GB |
| **Max file size** | 1 GB |
| **Monthly credits** | 5,000 (resets every 30 days) |
| **Workspaces** | 5 |
| **Shares** | 50 |
| **Members per workspace** | 5 |
| **Share invitations** | 10 per share |
| **Account auto-deletion** | Never |
### Credit Costs
All platform activity consumes credits from the monthly 5,000 allowance:
| Resource | Cost |
|----------|------|
| Storage | 100 credits/GB |
| Bandwidth | 212 credits/GB |
| AI chat tokens | 1 credit per 100 tokens |
| Document pages ingested | 10 credits/page |
| Video ingested | 5 credits/second |
| Audio ingested | 0.5 credits/second |
| Images ingested | 5 credits/image |
| File conversions | 25 credits/conversion |
When credits run out, the org enters a reduced-capability state and API calls return 402 Payment Required. The org is never deleted. Use `org` action `limits` to check current credit usage and remaining balance.
**When you hit 402 or run low on credits:**
- **Agent account (created via `auth` action `signup`):** Transfer the org to the human. Call `org` action `transfer-token-create` to generate a transfer token, then send the human the claim URL: `https://go.fast.io/claim?token=<token>`. Once they claim the org they can upgrade to a paid plan with unlimited credits. You retain admin access and can resume work immediately after the upgrade. This is the expected workflow -- agents build on the free plan, then hand off to humans who pay when they are ready.
- **Human account (signed in via `auth` action `signin`):** You cannot use the transfer/claim API. Tell the user they need to upgrade the org's billing plan directly. They can do this from the Fast.io dashboard or by calling `org` action `billing-create` to update their subscription to a paid plan.
### After Transfer -- Human Plan Options
Once an agent transfers an org to a human, the human gets a free plan (credit-based, no trial period) and can upgrade:
| Feature | Agent (Free) | Free (Human) | Pro | Business |
|---------|-------------|--------------|-----|----------|
| Monthly credits | 5,000 | 5,000 | Unlimited | Unlimited |
| Storage | 50 GB | 50 GB | 1 TB | 5 TB |
| Max file size | 1 GB | 1 GB | 25 GB | 50 GB |
| Workspaces | 5 | 5 | 10 | 1,000 |
| Shares | 50 | 50 | 1,000 | 50,000 |
The transfer flow is the primary way agents deliver value: set everything up on the free agent plan, then hand it off. The human upgrades when they are ready, and the agent retains admin access to keep managing things.
---
## 5. Tool Categories
The 19 tools use action-based routing. Each tool covers a specific area of the Fast.io platform and exposes multiple actions.
### auth
Authentication, sign-in/sign-up, two-factor authentication, API key management, and OAuth session management. This is always the starting point for any agent interaction.
**Actions:** signin, signout, signup, check, session, status, set-api-key, email-check, email-verify, password-reset-request, password-reset, 2fa-verify, 2fa-status, 2fa-enable, 2fa-disable, 2fa-send, 2fa-verify-setup, pkce-login, pkce-complete, api-key-create, api-key-update, api-key-list, api-key-get, api-key-delete, oauth-list, oauth-details, oauth-revoke, oauth-revoke-all
### user
Retrieve and update the current user profile, search for other users, manage invitations, upload and delete user assets (profile photos), check account eligibility, and list shares the user belongs to.
**Actions:** me, update, search, close, details-by-id, profiles, allowed, org-limits, list-shares, invitation-list, invitation-details, accept-all-invitations, asset-upload, asset-delete, asset-types, asset-list
### org
Organization CRUD, member management, billing and subscription operations, workspace creation, invitation workflows, asset management (upload, delete), organization discovery, and ownership transfer.
**Actions:** list, details, create, update, close, public-details, limits, list-workspaces, list-shares, create-workspace, billing-plans, billing-create, billing-cancel, billing-details, billing-activate, billing-reset, billing-members, billing-meters, members, invite-member, remove-member, update-member-role, member-details, leave, transfer-ownership, join, invitations-list, invitation-update, invitation-delete, transfer-token-create, transfer-token-list, transfer-token-delete, transfer-claim, discover-all, discover-available, discover-check-domain, discover-external, asset-upload, asset-delete, asset-types, asset-list
### workspace
Workspace-level settings, lifecycle operations (update, delete, archive, unarchive), listing and importing shares, managing workspace assets, workspace discovery, notes (create, read, update), quickshare management, metadata operations (template CRUD, assignment, file metadata get/set/delete, AI extraction), and workflow toggle (enable/disable tasks, worklogs, approvals, and todos).
**Actions:** list, details, update, delete, archive, unarchive, members, list-shares, import-share, available, check-name, create-note, read-note, update-note, quickshare-get, quickshare-delete, quickshares-list, metadata-template-create, metadata-template-delete, metadata-template-list, metadata-template-details, metadata-template-update, metadata-template-clone, metadata-template-assign, metadata-template-unassign, metadata-template-resolve, metadata-template-assignments, metadata-get, metadata-set, metadata-delete, metadata-extract, metadata-list-files, metadata-list-templates-in-use, metadata-versions, enable-workflow, disable-workflow
### share
Share CRUD, public details, archiving, password authentication, asset management, share name availability checks, and workflow toggle (enable/disable tasks, worklogs, approvals, and todos).
**Actions:** list, details, create, update, delete, public-details, archive, unarchive, password-auth, members, available, check-name, quickshare-create, enable-workflow, disable-workflow
### storage
File and folder operations within workspaces and shares. List, list recently modified files across all folders, create folders, move, copy, delete, rename, purge, restore, search, add files from uploads, add share links, transfer nodes, manage trash, version operations, file locking, and preview/transform URL generation. Requires `context_type` parameter (`workspace` or `share`).
**Actions:** list, recent, details, search, trash-list, create-folder, copy, move, delete, rename, purge, restore, add-file, add-link, transfer, version-list, version-restore, lock-acquire, lock-status, lock-release, preview-url, preview-transform
### upload
File upload operations. Single-step text file upload, chunked upload lifecycle (create session, stage binary blobs, upload chunks as plain text / base64 / blob reference, finalize, check status, cancel), web imports from external URLs, upload limits and file extension restrictions, and session management.
**Actions:** create-session, chunk, finalize, status, cancel, list-sessions, cancel-all, chunk-status, chunk-delete, stage-blob, text-file, web-import, web-list, web-cancel, web-status, limits, extensions
### download
Generate download URLs and ZIP archive URLs for workspace files, share files, and quickshare links. MCP tools cannot stream binary data -- these actions return URLs that can be opened in a browser or passed to download utilities. Requires `context_type` parameter (`workspace` or `share`) for file-url and zip-url actions. Responses include a `resource_uri` field (e.g. `download://workspace/{id}/{node_id}`) that MCP clients can use to read file content directly via MCP resources. Direct download URLs include `?error=html` so errors render as human-readable HTML in browsers.
**Actions:** file-url, zip-url, quickshare-details
### ai
AI-powered chat with RAG, semantic search, and document analysis in workspaces and shares. Create chats, send messages, read AI responses (with polling), list and manage chats, search indexed documents and code by meaning with relevance scores, publish private chats, generate AI share markdown, track AI token usage, and auto-title generation. Requires `context_type` parameter (`workspace` or `share`).
**Actions:** chat-create, chat-list, chat-details, chat-update, chat-delete, chat-publish, message-send, message-list, message-details, message-read, search, share-generate, transactions, autotitle
### comment
Comments are scoped to `{entity_type}/{parent_id}/{node_id}` where entity_type is `workspace` or `share`, parent_id is the 19-digit profile ID, and node_id is the storage node opaque ID. List comments on files (per-node and profile-wide with sort/limit/offset/filter params), add comments with optional reference anchoring (image regions, video/audio timestamps, PDF pages with text selection, text selections in markdown/notes), single-level threaded replies, recursive single delete, non-recursive bulk delete, get comment details, emoji reactions (one per user per comment), and workflow linking (link/unlink comments to tasks or approvals, reverse lookup). Comments use JSON request bodies.
**Actions:** list, list-all, add, delete, bulk-delete, details, reaction-add, reaction-remove, link, unlink, linked
### event
Search the audit/event log with rich filtering by category, subcategory, and event name (see **Event Filtering Reference** in section 7 for the full taxonomy). Get AI-powered summaries of activity, retrieve full details for individual events, list recent activity, and long-poll for activity changes.
**Actions:** search, summarize, details, activity-list, activity-poll
### member
Member management for organizations, workspaces, and shares. Add, remove, update roles, transfer ownership, leave, join, and join via invitation. Requires `entity_type` parameter (`workspace` or `share`).
**Actions:** add, remove, details, update, transfer-ownership, leave, join, join-invitation
### invitation
Invitation management for organizations, workspaces, and shares. List invitations, list by state, update, and delete. Requires `entity_type` parameter (`workspace` or `share`).
**Actions:** list, list-by-state, update, delete
### asset
Asset management (upload, delete, list, read) for organizations, workspaces, shares, and users. Requires `entity_type` parameter (`org`, `workspace`, `share`, or `user`).
**Actions:** upload, delete, types, list, read
### task
Task list and task management for workspaces and shares. Create and manage task lists, then create tasks within them with statuses, priorities, assignees, and dependencies. Supports bulk status changes, reordering, and markdown output. Tasks and lists include `created_by` (creator profile ID). Requires workflow to be enabled on the target entity.
**Actions:** list-lists, create-list, list-details, update-list, delete-list, list-tasks, create-task, task-details, update-task, delete-task, change-status, assign-task, bulk-status, move-task, reorder-tasks, reorder-lists
### worklog
Activity log for tracking agent work. After uploads, task changes, share creation, or any significant action, log what you did and why — builds a searchable audit trail for humans and AI. Also create urgent interjections that require acknowledgement. Entries are append-only and permanent. Requires workflow to be enabled on the target entity.
**Actions:** append, list, interject, details, acknowledge, unacknowledged
### approval
Formal approval requests scoped to tasks, storage nodes, or worklog entries. Create approval requests with designated approvers, then resolve them with approve or reject decisions. Requires workflow to be enabled on the target entity.
**Actions:** list, create, details, resolve
### todo
Simple flat checklists scoped to workspaces and shares. Create, update, delete, toggle todos individually or in bulk. Todos include `created_by` (creator profile ID). No nesting. Requires workflow to be enabled on the target entity.
**Actions:** list, create, details, update, delete, toggle, bulk-toggle
### apps
Interactive MCP App widget discovery and launching. List available widgets, get details for a specific widget, launch a widget with workspace or share context, and find widgets associated with a specific tool domain.
**Actions:** list, details, launch, get-tool-apps
---
## 6. Common Workflows
### 1. Create an Account and Sign In
See **Choosing the Right Approach** in section 2 for which option fits your scenario.
**Option 1 -- Autonomous agent (new account):**
1. Optionally call `auth` action `email-check` with the desired `email` to verify availability.
2. `auth` action `signup` with `first_name`, `last_name`, `email`, and `password` -- registers as an agent account (agent=true is sent automatically) and signs in immediately.
3. `auth` action `email-verify` with `email` -- sends a verification code. Then `auth` action `email-verify` with `email` and `email_token` -- validates the code. Required before using most endpoints.
4. `org` action `create` to create a new org on the agent plan, or `org` action `list` to check existing orgs.
**Option 2 -- Assisting a human (API key):**
1. The human creates an API key at `https://go.fast.io/settings/api-keys` and provides it to the agent.
2. Call `auth` action `set-api-key` with the API key. The key is validated against the API and stored in the session -- all subsequent tool calls are authenticated automatically. No account creation needed.
3. `org` action `list` and `org` action `discover-external` to discover all available organizations (see **Org Discovery**).
**Option 3 -- Agent invited to a human's org:**
1. Create an agent account with `auth` action `signup` (same as Option 1).
2. Have the human invite you via `org` action `invite-member` or `member` action `add` (with `entity_type: "workspace"`).
3. Accept invitations with `user` action `accept-all-invitations`.
4. `org` action `list` and `org` action `discover-external` to discover all available orgs (see **Org Discovery**). If the human only invited you to a workspace (not the org), it will only appear via `discover-external`.
**Returning users:**
1. `auth` action `signin` with `email` and `password`.
2. If `two_factor_required: true`, call `auth` action `2fa-verify` with the 2FA `code`.
3. `org` action `list` and `org` action `discover-external` to discover all available organizations (see **Org Discovery**).
### 2. Browse and Download a File
1. `org` action `list` and `org` action `discover-external` -- discover all available organizations (see **Org Discovery**). Note the `org_id` values.
2. `org` action `list-workspaces` with `org_id` -- get workspaces in the organization. Note the `workspace_id` values.
3. `storage` action `list` with `context_type: "workspace"`, `context_id` (workspace ID), and `node_id: "root"` -- browse the root folder. Note the `node_id` values for files and subfolders.
4. `storage` action `details` with `context_type: "workspace"`, `context_id`, and `node_id` -- get full details for a specific file (name, size, type, versions).
5. `download` action `file-url` with `context_type: "workspace"`, `context_id`, and `node_id` -- get a temporary download URL with an embedded token. The response also includes a `resource_uri` (e.g. `download://workspace/{id}/{node_id}`) that MCP clients can use to read file content directly. Return the download URL to the user, or use the resource URI to read the file through MCP.
### 3. Upload a File to a Workspace
**Text files (recommended):** Use `upload` action `text-file` with `profile_type: "workspace"`, `profile_id`, `parent_node_id`, `filename`, and `content` (plain text). This single action uploads the file and returns `new_file_id` on success. Internally it uses the Fast.io single-request upload pattern (one multipart POST with the file data), so there is no separate chunking, finalization, or polling step. Use this for code, markdown, CSV, JSON, config files, and any other text content.
**Binary files (choose the right approach):**
> **Understanding upload constraints.** The Fast.io API requires each chunk to be **≥ 1 MB** (except the last chunk of a session, which may be smaller). MCP tool calls have a practical transport limit of **~64 KB of raw binary** per call (~96 KB base64). This means multi-chunk binary uploads through MCP tool calls alone will fail for files larger than ~64 KB — each MCP-sized chunk is far below the 1 MB API minimum. Use `upload` action `limits` to check your plan's exact chunk size and file size limits.
**Option A: `web-import` (preferred for URL-accessible files)**
If the file has a URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox), use `upload` action `web-import`. Single call, no chunking, no base64. See Workflow 4 below.
**Option B: Single-chunk upload for small binary files (≤ ~64 KB)**
Small files that fit in one MCP tool call can be uploaded as a single chunk:
1. `upload` action `create-session` with `profile_type`, `profile_id`, `parent_node_id`, `filename`, and `filesize` in bytes.
2. `upload` action `chunk` with `upload_id`, `chunk_number: 1`, and `data` (base64-encoded file, ≤96 KB base64 / ~64 KB binary). Since this is the only chunk, the API's "1 small chunk allowed" rule permits it.
3. `upload` action `finalize` with `upload_id`.
**Option C: `POST /blob` sidecar endpoint for larger binary files**
For files > ~64 KB, use the HTTP blob endpoint to bypass MCP transport limits. The `POST /blob` endpoint accepts raw binary via HTTP (no base64, no size splitting within MCP). Stage blobs of **≥ 1 MB each** (except the last), then reference them in chunk calls:
1. `upload` action `create-session` with `profile_type`, `profile_id`, `parent_node_id`, `filename`, and `filesize`.
2. For each chunk: `POST /blob` with raw binary (≥ 1 MB, ≤ 100 MB). Returns `blob_id`.
3. `upload` action `chunk` with `upload_id`, `chunk_number`, and `blob_ref: "<blob_id>"`.
4. `upload` action `finalize` with `upload_id`.
**Option D: External upload tooling**
For reliable binary uploads of any size, use an external HTTP client (Python requests, curl, etc.) to call the Fast.io REST API upload endpoints directly, bypassing MCP transport constraints entirely. Use MCP for control-plane tasks (session creation, finalization, status) and the external client for the data plane (chunk uploads).
Three options for passing chunk data (provide exactly one):
- **`content`** — for text (strings, code, JSON, etc.). Do NOT use `data` for text.
- **`data`** — base64-encoded binary. Limited by MCP transport to **~96 KB base64 (~64 KB binary) per call**. Only practical for single-chunk small files.
- **`blob_ref`** — blob ID from `upload` action `stage-blob` or `POST /blob`. The `POST /blob` approach is recommended for larger files since it bypasses MCP transport limits.
`upload` action `finalize` with `upload_id` triggers file assembly and polls until stored. Returns the final session state with `status: "stored"` or `"complete"` on success (including `new_file_id`), or throws on failure. Terminal failure states: `assembly_failed` (chunks could not be assembled) and `store_failed` (assembled file could not be stored — check `status_message` for details). The file is automatically added to the target workspace and folder specified during session creation -- no separate add-file call is needed.
**Upload status states:**
| Status | Meaning | Terminal? |
|--------|---------|-----------|
| `ready` | Session created, awaiting chunks | No |
| `uploading` | Chunks being received | No |
| `assembling` | Assembly in progress | No |
| `complete` | Assembled, awaiting storage import | No |
| `storing` | Being imported to storage | No |
| `stored` | Done — file is in storage, `new_file_id` available | Yes (success) |
| `assembly_failed` | Assembly error | Yes (failure) |
| `store_failed` | Storage import failed | Yes (failure) |
**Note:** `storage` action `add-file` is only needed if you want to link the upload to a *different* location than the one specified during session creation.
**Same-name uploads:** If a file with the same name already exists in the target folder, the upload **replaces** (overwrites) it. The previous content is preserved as a version. To keep both files, rename before uploading.
### 4. Import a File from URL
Use this when you have a file URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox) and want to add it to a workspace without downloading locally.
1. `upload` action `web-import` with `url` (the source URL), `profile_type: "workspace"`, `profile_id` (the workspace ID), and `parent_node_id` (target folder or `"root"`). Returns an `upload_id`.
2. `upload` action `web-status` with `upload_id` -- check import progress. The server downloads the file, scans it, generates previews, and indexes it for AI (if intelligence is enabled).
3. The file appears in the workspace storage tree once the job completes.
### 5. Deliver Files to a Client
Create a branded, professional data room for outbound file delivery. This replaces raw download links, email attachments, and S3 presigned URLs.
1. Upload files to the workspace (see workflow 3 or 4).
2. `share` action `create` with `workspace_id`, `name`, and `type: "send"` -- creates a Send share. Returns a `share_id`.
3. `share` action `update` with `share_id` to configure:
- `password` -- require a password for access
- `expiry_date` -- auto-expire the share after a set period
- `access_level` -- Members Only, Org Members, Registered Users, or Public
- `allow_downloads` -- enable or disable file downloads
- Branding options: `background_color`, `accent_color`, `gradient_color`
- `post_download_message` and `post_download_url` -- show a message after download
4. `member` action `add` with `entity_type: "share"`, `entity_id` (share ID), and `email_or_user_id` -- adds the recipient. An invitation is sent if they do not have a Fast.io account.
5. `asset` action `upload` with `entity_type: "share"` and `entity_id` (share ID) to add a logo or background image for branding.
6. The recipient sees a branded page with instant file preview, not a raw download link.
### 6. Collect Documents from a User
Create a Receive share so humans can upload files directly to you -- no email attachments, no cloud drive links.
1. `share` action `create` with `workspace_id`, `name` (e.g., "Upload your tax documents here"), and `type: "receive"`. Returns a `share_id`.
2. `share` action `update` with `share_id` to set access level, expiration, and branding as needed.
3. `member` action `add` with `entity_type: "share"`, `entity_id` (share ID), and `email_or_user_id` to invite the uploader.
4. The human uploads files through a clean, branded interface.
5. Files appear in your workspace. If intelligence is enabled, they are auto-indexed by AI.
6. Use `ai` action `chat-create` with `context_type: "share"` scoped to the receive share's folder to ask questions like "Are all required forms present?"
### 7. Build a Knowledge Base
Create an intelligent workspace that auto-indexes all content for RAG queries.
1. `org` action `create-workspace` with `org_id`, `name`, and `intelligence: "true"` (this workflow specifically requires intelligence for RAG).
2. Upload reference documents (see workflow 3 or 4). AI auto-indexes and summarizes everything on upload.
3. `ai` action `chat-create` with `context_type: "workspace"`, `context_id` (workspace ID), `query_text`, `type: "chat_with_files"`, and `folders_scope` (comma-separated `nodeId:depth` pairs) to query across folders or the entire workspace.
4. `ai` action `message-read` with `context_type: "workspace"`, `context_id`, `chat_id`, and `message_id` -- polls until the AI response is complete. Returns `response_text` and `citations` pointing to specific files, pages, and snippets.
5. `storage` action `search` with `context_type: "workspace"`, `context_id`, and a query string for semantic search -- find files by meaning, not just filename.
6. Answers include citations to specific pages and files. Pass these back to the user with source references.
### 8. Ask AI About Files
Two modes depending on whether intelligence is enabled on the workspace.
**With intelligence (persistent index):**
1. `ai` action `chat-create` with `context_type: "workspace"`, `context_id` (workspace ID), `query_text`, `type: "chat_with_files"`, and either `files_scope` (comma-separated `nodeId:versionId` pairs) or `folders_scope` (comma-separated `nodeId:depth` pairs, depth range 1-10). **Important:** `files_scope` and `files_attach` are mutually exclusive — sending both will error. Returns `chat_id` and `message_id`.
2. `ai` action `message-read` with `context_type: "workspace"`, `context_id`, `chat_id`, and `message_id` -- polls the API up to 15 times (2-second intervals, approximately 30 seconds) until the AI response is complete. Returns `response_text` and `citations`. **Tip:** If the built-in polling window expires, use `event` action `activity-poll` with the workspace ID instead of calling `message-read` in a loop — see the Activity Polling section above.
3. `ai` action `message-send` with `context_type: "workspace"`, `context_id`, `chat_id`, and `query_text` for follow-up questions. Returns a new `message_id`.
4. `ai` action `message-read` again with the new `message_id` to get the follow-up response.
**Without intelligence (file attachments):**
1. `ai` action `chat-create` with `context_type: "workspace"`, `context_id`, `query_text`, `type: "chat_with_files"`, and `files_attach` pointing to specific files (comma-separated `nodeId:versionId`, max 20 files / 200 MB). Files must have `ai.attach: true` (check via `storage` action `details`). The AI reads attached files directly without persistent indexing.
2. `ai` action `message-read` to get the response. No ingestion credit cost -- only chat token credits are consumed.
### 9. Set Up a Project for a Human
The full agent-to-human handoff workflow. This is the primary way agents deliver value on Fast.io.
1. `org` action `create` -- creates a new org on the agent billing plan. The agent becomes owner. An agent-plan subscription (free, 50 GB, 5,000 credits/month) is created automatically.
2. `org` action `create-workspace` with `org_id` and `name` -- create workspaces for each project area.
3. `storage` action `create-folder` with `context_type: "workspace"` to build out folder structure (templates, deliverables, reference docs, etc.).
4. Upload files to each workspace (see workflow 3 or 4).
5. `share` action `create` with `type: "send"` for client deliverables, `type: "receive"` for intake/collection.
6. `share` action `update` to configure branding, passwords, expiration, and access levels on each share.
7. `org` action `invite-member` or `member` action `add` with `entity_type: "workspace"` to invite team members.
8. `org` action `transfer-token-create` with `org_id` -- generates a transfer token valid for 72 hours. Send the claim URL (`https://go.fast.io/claim?token=<token>`) to the human.
9. Human clicks the link and claims the org. They become owner, agent retains admin access. Human gets a free plan.
### 10. Manage Organization Billing
1. `org` action `billing-plans` -- list all available billing plans with pricing and features.
2. `org` action `billing-create` with `org_id` and optionally `billing_plan` -- create or update a subscription. For new subscriptions, this creates a Stripe Setup Intent.
3. `org` action `billing-details` with `org_id` -- check the current subscription status, Stripe customer info, and payment details.
4. `org` action `limits` with `org_id` -- check credit usage against plan limits, including storage, transfer, AI tokens, and billing period info.
### 11. Manage Tasks in a Workspace
Track work with structured task lists and tasks.
1. `workspace` action `enable-workflow` with `workspace_id` -- enable workflow features (required before using task, worklog, approval, or todo tools).
2. `task` action `create-list` with `profile_type: "workspace"`, `profile_id` (workspace ID), and `name` -- create a task list. Returns `list_id`.
3. `task` action `create-task` with `list_id`, `title`, and optionally `description`, `priority` (0-4), `assignee_id`, `dependencies`, `node_id`, and `status` -- add tasks to the list.
4. `task` action `list-tasks` with `list_id` -- view all tasks, optionally filtered by `status` or `assignee`.
5. `task` action `change-status` with `list_id`, `task_id`, and `status` -- update task progress (`pending` → `in_progress` → `complete`).
6. `task` action `assign-task` with `list_id`, `task_id`, and `assignee_id` -- assign work to team members.
7. `task` action `bulk-status` with `list_id`, `task_ids`, and `status` -- batch-update up to 100 tasks at once.
### 12. Full Agent Workflow (Tasks + Worklogs + Approvals)
The complete agentic workflow pattern: plan work, execute with logging, and gate decisions with approvals.
1. `workspace` action `enable-workflow` with `workspace_id` -- enable workflow features on the workspace.
2. `workspace` action `create-note` -- create context notes with project background, requirements, and reference material.
3. `task` action `create-list` -- create task lists for each work phase (e.g., "Research", "Implementation", "Review").
4. `task` action `create-task` -- add tasks linked to context. Include descriptive titles and reference note node_ids in descriptions.
5. `task` action `change-status` with `status: "in_progress"` -- mark a task as started.
6. `worklog` action `append` with `entity_type` ("task", "task_list", "node", or "profile"), `entity_id` (the corresponding entity's opaque ID, or profile 19-digit ID for entity_type "profile"), and `content` -- log progress, decisions, and reasoning as you work. Build a chronological narrative.
7. If a priority correction is needed: `worklog` action `interject` -- creates an urgent entry that requires acknowledgement from other participants.
8. `worklog` action `unacknowledged` -- check for unacknowledged interjections before proceeding.
9. `worklog` action `acknowledge` -- mark interjections as seen.
10. When a decision needs sign-off: `approval` action `create` with `profile_id`, `description`, `entity_type` ("task", "node", or "worklog_entry"), and optionally `approver_id` -- request formal approval.
11. `approval` action `resolve` with `resolve_action: "approve"` or `"reject"` and optional `comment` -- approvers resolve the request.
12. `task` action `change-status` with `status: "complete"` -- mark completed tasks.
13. `todo` action `create` -- track simple checklist items alongside the main task flow.
14. With intelligence enabled, `ai` action `chat-create` -- the AI can search across notes, task descriptions, and worklogs to answer questions about the project.
---
## 7. Key Patterns and Gotchas
### ID Format
Profile IDs (org, workspace, share, user) are 19-digit numeric strings. Most endpoints also accept custom names as identifiers -- workspace folder names, share URL names, org domain names, or user email addresses. Both formats are interchangeable in URL path parameters.
All other IDs (node IDs, upload IDs, chat IDs, comment IDs, invitation IDs, etc.) are 30-character alphanumeric opaque IDs (displayed with hyphens). Do not apply numeric validation to these.
### Pagination
Two pagination styles are used depending on the endpoint:
**Cursor-based (storage list endpoints):** `sort_by`, `sort_dir`, `page_size`, and `cursor`. The response includes a `next_cursor` value when more results are available. Pass this cursor in the next call to retrieve the next page. Page sizes are typically 100, 250, or 500. Used by: `storage` action `list` (with `context_type: "workspace"` or `"share"`).
**Limit/offset (all other list endpoints):** `limit` (1-500, default 100) and `offset` (default 0). Used by: `org` actions `list`, `members`, `list-workspaces`, `list-shares`, `billing-members`, `discover-all`, `discover-external`; `share` actions `list`, `members`; `workspace` actions `list`, `members`, `list-shares`; `user` action `list-shares`; `storage` action `search`.
### Binary Downloads
MCP tools return download URLs -- they never stream binary content directly. `download` action `file-url` (with `context_type: "workspace"` or `"share"`) and `download` action `quickshare-details` call the `/requestread/` endpoint to obtain a temporary token, then construct a full download URL. The agent should return these URLs to the user or pass them to a download utility.
`download` actions `zip-url` (workspace and share) return the URL along with the required `Authorization` header value.
### Binary Uploads
Three approaches for uploading binary data as chunks, each suited to different situations.
> **Prefer `web-import` for URL-accessible files.** If the binary file is accessible via any URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox), use `upload` action `web-import` instead of chunked upload. It's a single tool call — no chunking, no base64, no session management. Only use chunked upload when you have local binary data with no URL available.
> **Chunk size limit for MCP agents.** MCP tool parameters pass through the AI model's output, which limits how much data you can include in a single tool call. **Keep each chunk's base64 `data` under 32 KB** (~24 KB of binary). For example, a 145 KB PDF needs at least 6 chunks, and even a 17 KB file should be split into 1-2 chunks rather than assumed to fit in one call. The `create-session` response includes a `recommended_mcp_chunk_bytes` hint (default 24576) — use it to calculate the number of chunks: `ceil(filesize / recommended_mcp_chunk_bytes)`. Always split files into multiple chunks when using `data` or `stage-blob` through MCP tool calls.
> **Common pitfall: do NOT pre-process binary data into intermediate formats.** Pass base64 data directly in the `data` parameter of `chunk` or `stage-blob` tool calls. Do NOT read binary files into Python/JSON variables, pickle them, or save to temp files hoping to reference them later — the MCP tool can only receive data through its own parameters. If you have local binary files, base64-encode them in ≤32 KB segments and pass each segment directly as the `data` parameter in sequential `stage-blob` → `chunk` calls. Create upload sessions immediately before uploading — sessions expire, so do not debug between creating a session and uploading chunks.
**1. `data` parameter (base64) — simplest for MCP agents**
Pass base64-encoded binary directly in the `data` parameter of `upload` action `chunk`. No extra steps required. Works with any MCP client. Adds ~33% size overhead from base64 encoding. **Split files into chunks of ≤24 KB binary (≤32 KB base64)** to stay within MCP client parameter limits.
**2. `stage-blob` action — MCP tool-based blob staging**
Use `upload` action `stage-blob` with `data` (base64) to pre-stage binary data as a blob. Returns a `blob_id` that you pass as `blob_ref` in the chunk call. Useful when you want to decouple staging from uploading, or when preparing multiple chunks in advance. The same **32 KB base64 limit per call** applies — stage one chunk-sized piece at a time.
**Flow:**
1. `upload` action `stage-blob` with `data` (base64-encoded binary, ≤32 KB). Returns `{ "blob_id": "<uuid>", "size": <bytes> }`.
2. `upload` action `chunk` with `blob_ref: "<blob_id>"`. The server retrieves the staged bytes and uploads them.
**3. `POST /blob` endpoint — HTTP blob staging for non-MCP clients**
A sidecar HTTP endpoint that accepts raw binary data outside the JSON-RPC pipe. This avoids base64 encoding entirely — useful for clients that can make direct HTTP requests alongside MCP tool calls. No chunk size splitting needed with this approach.
**Flow:**
1. `POST /blob` with headers `Mcp-Session-Id: <session_id>` and `Content-Type: application/octet-stream`. Send raw binary bytes as the request body. Returns `{ "blob_id": "<uuid>", "size": <bytes> }` (HTTP 201).
2. `upload` action `chunk` with `blob_ref: "<blob_id>"`.
**Blob constraints (apply to both staging methods):**
- Blobs expire after **5 minutes**. Stage and consume them promptly.
- Each blob is consumed (deleted) on first use — it cannot be reused.
- Maximum blob size: **100 MB**.
- SSE transport clients must add `?transport=sse` to the `/blob` URL.
### Event Filtering Reference
The `event` tool's `search` and `summarize` actions accept `category`, `subcategory`, and `event` parameters to narrow results. Use these to target specific activity instead of scanning all events.
#### Event Categories
| Category | What It Covers |
|---|---|
| `user` | Account creation, updates, deletion, avatar changes |
| `org` | Organization lifecycle, settings, transfers |
| `workspace` | Workspace creation, updates, archival, file operations |
| `share` | Share lifecycle, settings, file operations |
| `node` | File and folder operations (cross-profile) |
| `ai` | AI chat, summaries, RAG indexing |
| `invitation` | Member invitations sent, accepted, declined |
| `billing` | Subscriptions, trials, credit usage |
| `domain` | Custom domain configuration |
| `apps` | Application integrations |
| `metadata` | Metadata extraction, templates, key-value updates |
#### Event Subcategories
| Subcategory | What It Covers |
|---|---|
| `storage` | File/folder add, move, copy, delete, restore, download |
| `comments` | Comment created, updated, deleted, mentioned, replied, reaction |
| `members` | Member added/removed from org, workspace, or share |
| `lifecycle` | Profile created, updated, deleted, archived |
| `settings` | Configuration and preference changes |
| `security` | Security-related events (2FA, password) |
| `authentication` | Login, SSO, session events |
| `ai` | AI processing, chat, indexing |
| `invitations` | Invitation management |
| `billing` | Subscription and payment events |
| `assets` | Avatar/asset updates |
| `upload` | Upload session management |
| `transfer` | Cross-profile file transfers |
| `quickshare` | Quick share operations |
| `metadata` | Metadata operations |
#### Common Event Names
**File operations (workspace):** `workspace_storage_file_added`, `workspace_storage_file_deleted`, `workspace_storage_file_moved`, `workspace_storage_file_copied`, `workspace_storage_file_updated`, `workspace_storage_file_restored`, `workspace_storage_folder_created`, `workspace_storage_folder_deleted`, `workspace_storage_folder_moved`, `workspace_storage_download_token_created`, `workspace_storage_zip_downloaded`, `workspace_storage_file_version_restored`, `workspace_storage_link_added`
**File operations (share):** `share_storage_file_added`, `share_storage_file_deleted`, `share_storage_file_moved`, `share_storage_file_copied`, `share_storage_file_updated`, `share_storage_file_restored`, `share_storage_folder_created`, `share_storage_folder_deleted`, `share_storage_folder_moved`, `share_storage_download_token_created`, `share_storage_zip_downloaded`
**Comments:** `comment_created`, `comment_updated`, `comment_deleted`, `comment_mentioned`, `comment_replied`, `comment_reaction`
**Membership:** `added_member_to_org`, `added_member_to_workspace`, `added_member_to_share`, `removed_member_from_org`, `removed_member_from_workspace`, `removed_member_from_share`, `membership_updated`
**Workspace lifecycle:** `workspace_created`, `workspace_updated`, `workspace_deleted`, `workspace_archived`, `workspace_unarchived`
**Share lifecycle:** `share_created`, `share_updated`, `share_deleted`, `share_archived`, `share_unarchived`, `share_imported_to_workspace`
**AI:** `ai_chat_created`, `ai_chat_new_message`, `ai_chat_updated`, `ai_chat_deleted`, `ai_chat_published`, `node_ai_summary_created`, `workspace_ai_share_created`
**Metadata:** `metadata_kv_update`, `metadata_kv_delete`, `metadata_kv_extract`, `metadata_template_update`, `metadata_template_delete`, `metadata_template_settings_update`, `metadata_view_update`, `metadata_view_delete`, `metadata_template_select`
**Quick shares:** `workspace_quickshare_created`, `workspace_quickshare_updated`, `workspace_quickshare_deleted`, `workspace_quickshare_file_downloaded`, `workspace_quickshare_file_previewed`
**Invitations:** `invitation_email_sent`, `invitation_accepted`, `invitation_declined`
**User:** `user_created`, `user_updated`, `user_deleted`, `user_email_reset`, `user_asset_updated`
**Org:** `org_created`, `org_updated`, `org_closed`, `org_transfer_token_created`, `org_transfer_completed`
**Billing:** `subscription_created`, `subscription_cancelled`, `billing_free_trial_ended`
#### Example Queries
- **Recent comments in a workspace:** `event` action `search` with `workspace_id` and `subcategory: "comments"`
- **Files uploaded to a share:** `event` action `search` with `share_id` and `event: "share_storage_file_added"`
- **All membership changes across an org:** `event` action `search` with `org_id` and `subcategory: "members"`
- **AI activity in a workspace:** `event` action `search` with `workspace_id` and `category: "ai"`
- **Who downloaded files from a share:** `event` action `search` with `share_id` and `event: "share_storage_download_token_created"`
### Activity Polling
Three mechanisms for detecting changes, listed from most to least preferred:
1. **`event` action `activity-poll`** — The server holds the connection for up to 95 seconds and returns immediately when something changes. Returns activity keys (e.g. `ai_chat:{chatId}`, `storage`, `members`) and a `lastactivity` timestamp for the next poll. Use this for any "wait for something to happen" scenario, including AI chat completion.
2. **WebSocket** — For real-time push events. Best for live UIs.
3. **`event` action `activity-list`** — Retrieves recent activity events on demand. Use when you need a one-time snapshot rather than continuous monitoring.
**Why this matters:** Do not poll detail endpoints (like `ai` action `message-read`) in tight loops. Instead, use `event` action `activity-poll` to detect when something has changed, then fetch the details once.
#### AI Message Completion
`ai` action `message-read` (with `context_type: "workspace"` or `"share"`) implements built-in polling (up to 15 attempts, 2-second intervals). If the response is still processing after that window, use `event` action `activity-poll` with the workspace or share ID instead of calling the read action in a loop:
1. Call `event` action `activity-poll` with `entity_id` set to the workspace/share ID.
2. When the response includes an `ai_chat:{chatId}` key matching your chat, call `ai` action `message-read` once to get the completed response.
#### Activity Poll Workflow
1. Make an API call (e.g. `ai` action `chat-create`) and note the `server_date` field in the response.
2. Call `event` action `activity-poll` with `entity_id` (workspace or share ID) and `lastactivity` set to the `server_date` value.
3. The server holds the connection. When something changes (or the wait period expires), it returns activity keys.
4. Inspect the keys to determine what changed, then fetch the relevant detail (e.g. `ai` action `message-read`, `storage` action `list`).
5. Use the new `lastactivity` value from the poll response (or the latest `server_date`) for the next poll call. Repeat as needed.
### Trash, Delete, and Purge
- `storage` action `delete` (with `context_type: "workspace"` or `"share"`) moves items to the trash. They are recoverable.
- `storage` action `restore` recovers items from the trash.
- `storage` action `purge` permanently and irreversibly deletes items from the trash.
Always confirm with the user before calling purge operations.
### Node Types
Storage nodes can be files, folders, notes, or links. The type is indicated in the storage details response. Notes are markdown files created with `workspace` action `create-note`, read with `workspace` action `read-note`, and updated with `workspace` action `update-note`. Links are share reference nodes created with `storage` action `add-link`.
### Text Content and Newlines
All text content (notes, comments, worklogs, file uploads, descriptions) must use Unix-style line feeds (`\n`, U+000A) for newlines. The frontend normalizes all line endings to `\n` before saving -- Windows-style `\r\n` (CRLF) and legacy Mac `\r` (CR) are converted automatically. Agents should use `\n` exclusively to avoid mismatches in content comparison and display.
**Encoding rules:**
- **Newlines:** Use `\n` (U+000A). Never send `\r\n` or `\r` alone.
- **Allowed control characters:** Only `\t` (U+0009), `\n` (U+000A), and `\r` (U+000D) survive server-side sanitization. All other Unicode control characters (`\p{C}`) are stripped.
- **Empty lines in markdown:** Use two consecutive `\n` characters (`\n\n`) for paragraph breaks. Do not use non-breaking spaces (U+00A0) or other whitespace characters as line placeholders.
- **Trailing newlines:** Content may or may not end with a trailing `\n`. Do not assume either convention -- both are valid.
This applies to: `workspace` actions `create-note` and `update-note`, `upload` action `text-file`, `comment` action `add`, `worklog` actions `append` and `interject`, and any other tool that accepts free-text or markdown content.
### Error Pattern
Failed API calls throw errors with two fields: `code` (unique numeric error ID) and `text` (human-readable description). Tools surface these as error text in the MCP response. Common HTTP status codes include 401 (unauthorized), 403 (forbidden), 404 (not found), and 429 (rate limited).
### Session State
The auth token, user ID, email, and token expiry are persisted in the server session. There is no need to pass tokens between tool calls. The session survives across multiple tool invocations within the same MCP connection.
### Human-Facing URLs
MCP tools manage data via the API, but humans access Fast.io through a web browser. **Always use the `web_url` field from tool responses** -- it is a ready-to-use, clickable URL for the resource. Include it in your responses whenever you create or reference a workspace, share, file, note, or transfer. The human cannot see API responses directly -- the URL you provide is how they get to their content. Fall back to the URL patterns below only when `web_url` is absent (e.g., share-context storage operations):
> **Automatic `web_url` field.** All entity-returning tool responses include a `web_url` field — a ready-to-use, human-friendly URL for the resource. **NEVER construct URLs manually — always use the `web_url` field from tool responses.** It appears on: org list/details/create/update/public-details/discover-*, org list-workspaces/list-shares, workspace list/details/update/available/list-shares, share list/details/create/update/public-details/available, storage list/details/search/trash-list/copy/move/rename/restore/add-file/create-folder/version-list/version-restore/preview-url/preview-transform, quickshare create/get/list, upload text-file/finalize, download file-url/quickshare-details, AI chat-create/chat-details/chat-list, transfer-token create/list, and notes create/update. Fall back to the URL patterns below only when `web_url` is absent (e.g., share context storage operations).
Organization `domain` values become subdomains: `"acme"` → `https://acme.fast.io/`. The base domain `go.fast.io` handles public routes that do not require org context.
#### Authenticated Links (require login)
| What the human needs | URL pattern |
|---------------------|-------------|
| Workspace root | `https://{domain}.fast.io/workspace/{folder_name}/storage/root` |
| Specific folder | `https://{domain}.fast.io/workspace/{folder_name}/storage/{node_id}` |
| File preview | `https://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}` |
| File with specific comment | `https://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?comment={comment_id}` |
| File at video/audio time | `https://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?t={seconds}` |
| File at PDF page | `https://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?p={page_num}` |
| AI chat in workspace | `https://{domain}.fast.io/workspace/{folder_name}/storage/root?chat={chat_id}` |
| Note in workspace | `https://{domain}.fast.io/workspace/{folder_name}/storage/root?note={note_id}` |
| Note preview | `https://{domain}.fast.io/workspace/{folder_name}/preview/{note_id}` |
| Browse workspaces | `https://{domain}.fast.io/browse-workspaces` |
| Edit share settings | `https://{domain}.fast.io/workspace/{folder_name}/share/{custom_name}` |
| Org settings | `https://{domain}.fast.io/settings` |
| Billing | `https://{domain}.fast.io/settings/billing` |
#### Public Links (no login required)
| What the human needs | URL pattern |
|---------------------|-------------|
| Public share | `https://go.fast.io/shared/{custom_name}/{title-slug}` |
| Org-branded share | `https://{domain}.fast.io/shared/{custom_name}/{title-slug}` |
| File in share | `https://go.fast.io/shared/{custom_name}/{title-slug}/preview/{node_id}` |
| File in share with comment | `https://go.fast.io/shared/{custom_name}/{title-slug}/preview/{node_id}?comment={comment_id}` |
| QuickShare | `https://go.fast.io/quickshare/{quickshare_id}` |
| Claim org transfer | `https://go.fast.io/claim?token={transfer_token}` |
| Onboarding | `https://go.fast.io/onboarding` or `https://go.fast.io/onboarding?orgId={org_id}&orgDomain={domain}` |
#### Where the values come from
| Value | API source |
|-------|-----------|
| `domain` | `org` action `create` or `details` response |
| `folder_name` | `org` action `create-workspace` or `workspace` action `details` response |
| `node_id` | `storage` action `list`, `create-folder`, or `add-file` response |
| `custom_name` | `share` action `create` or `details` response (the `{title-slug}` is cosmetic -- the share resolves on `custom_name` alone) |
| `quickshare_id` | `workspace` action `quickshare-create` response |
| `transfer_token` | `org` action `transfer-token-create` response |
| `chat_id` | `ai` action `chat-create` or `chat-list` response |
| `note_id` | `workspace` action `create-note` or `storage` action `list` response (node opaque ID) |
| `comment_id` | `comment` action `add` or `list` response |
| `org_id` | `org` action `create` or `list` response |
**Always provide URLs to the human in these situations:**
- **Created a workspace?** Include the workspace URL in your response. Example: `https://acme.fast.io/workspace/q4-reports/storage/root`
- **Created or configured a share?** Include the share URL. Example: `https://go.fast.io/shared/q4-financials/Q4-Financial-Report` -- this is the branded page the human (or their recipients) will open.
- **Generated a transfer token?** Include the claim URL. Example: `https://go.fast.io/claim?token=abc123` -- this is the only way the human can claim ownership.
- **Uploaded files or created folders?** Include the workspace URL pointing to the relevant folder so the human can see what you built.
- **Human asks "where can I see this?"** Construct the URL from API response data you already have and provide it.
**Important:** The `domain` is the org's domain string (e.g. `acme`), not the numeric org ID. The `folder_name` is the workspace's folder name string (e.g. `q4-reports`), not the numeric workspace ID. Both are returned by their respective API tools.
### Response Hints (`_next`, `_warnings`, and `_recovery`)
Workflow-critical tool responses include a `_next` field -- a short array of suggested next actions using exact tool and action names. Use these hints to guide your workflow instead of guessing what to do next. Example:
```json
{
"workspace_id": "...",
"web_url": "https://acme.fast.io/workspace/q4-reports/storage/root",
"_next": [
"Upload files: upload action text-file or web-import",
"Create a share: share action create",
"Query with AI: ai action chat-create"
]
}
```
**`_warnings`** appear on destructive, irreversible, or potentially problematic actions. Always read warnings before proceeding -- they flag permanent consequences or important caveats. Actions with `_warnings`: storage purge, storage bulk copy/move/delete/restore (partial failures), workspace details (intelligence=false), workspace update (intelligence=false), workspace archive/delete, org close, org billing-create, share delete, share archive, share update (type change), ai chat-delete, download file-url (token expiry), download zip-url (auth required), upload stage-blob (5-min expiry), org transfer-token-create.
**`_recovery`** hints appear on error responses (when `isError: true`). They provide recovery actions based on HTTP status codes AND error message pattern matching. Error messages also include action context (e.g., "during: org create") to help pinpoint the failing operation.
| HTTP Status | Recovery |
|-------------|----------|
| 400 | Check required parameters and ID formats |
| 401 | Re-authenticate: auth action signin or pkce-login |
| 402 | Credits exhausted -- check balance: org action limits |
| 403 | Permission denied -- check role: org action details |
| 404 | Resource not found -- verify the ID, use list actions to discover valid IDs |
| 409 | Conflict -- resource may already exist |
| 413 | Request too large -- reduce file/chunk size |
| 422 | Validation error -- check field formats and constraints |
| 429 | Rate limited -- wait 2-4s and retry with exponential backoff |
| 500/503 | Server error -- retry after 2-5 seconds |
Pattern-based recovery: error messages are also matched against common patterns (e.g., "email not verified", "workspace not found", "intelligence disabled") to provide specific recovery steps even when the HTTP status is generic.
**`ai_capabilities`** is included in workspace details responses. It shows which AI modes are available based on the workspace intelligence setting:
- Intelligence ON: `files_scope`, `folders_scope`, `files_attach` (full RAG with indexed document search)
- Intelligence OFF: `files_attach` only (max 20 files, 200 MB, no RAG indexing)
**`_ai_state_legend`** is included in storage list and search responses when files have AI indexing state. States: `ready` (indexed, queryable), `pending` (queued), `inprogress` (indexing), `disabled` (intelligence off), `failed` (re-upload needed). Also includes `_attach_field` explaining the `ai.attach` boolean — check this flag before using `files_attach`.
**`_context`** provides contextual metadata on specific responses. Currently used by comment add when anchoring is involved, providing `anchor_formats` with the expected format for image regions, video/audio timestamps, and PDF pages.
**All tool actions now include `_next` hints.** Every successful tool response includes contextual next-step suggestions. Key workflow transitions: auth → org list/create, org create → workspace create, workspace create → upload/share/AI, upload → AI chat/comment/download, share create → add files/members, AI chat create → message read. The hints include the exact tool name, action, and relevant IDs from the current response.
**Tool annotations:** Tools include MCP annotation hints -- `readOnlyHint`, `destructiveHint`, `idempotentHint` (download, event), and `openWorldHint` (org, user, workspace, share, storage) -- to help clients understand tool behavior without documentation.
**Resource completion and listing:** The workspace and share download resource templates support both dynamic listing (`resources/list`) and tab-completion (`completion/complete`). Dynamic listing shows root-level files across workspaces and shares in the client's resource picker. Tab-completion suggests valid workspace and share IDs as you type.
### Unauthenticated Tools
The following actions work without a session: `auth` actions `signin`, `signup`, `set-api-key`, `pkce-login`, `email-check`, `password-reset-request`, `password-reset`; and `download` action `quickshare-details`.
---
## 8. MCP Apps (Interactive UI Widgets)
Fast.io MCP Server includes interactive HTML5 widgets that render rich UIs directly in agent conversations. Widgets communicate with the MCP server through tool calls and display file browsers, dashboards, workflow managers, and more.
### Available Widgets
| Widget | Resource URI | Description |
|--------|-------------|-------------|
| File Picker | `widget://file-picker` | Browse and pick files to attach to your conversation — navigate folders, search, preview, select files for the agent. Also supports file management (upload, move, copy, delete) in workspace and share contexts |
| Workspace Picker | `widget://workspace-picker` | Org/workspace/share selection with search, 4-step workspace creation wizard, 5-step share creation wizard |
| File Viewer | `widget://file-viewer` | Unified file preview (image, PDF, video, audio, code, spreadsheet) with info panel (details, versions, AI summary, metadata) |
| Workflow Manager | `widget://workflow` | Task board, task detail, approvals panel, todos checklist, worklog viewer |
| Comments Panel | `widget://comments` | Threaded comments, reactions, anchored comments (image regions, timestamps) |
| Uploader | `widget://uploader` | Upload files to a workspace or share with drag-and-drop, chunked binary uploads, single-step text file creation, and web URL imports with real-time progress tracking |
### Uploader Widget
The Uploader widget provides a 4-step file upload flow:
1. **Choose destination** -- select an organization, then a workspace or share, then optionally navigate to a subfolder
2. **Select files** -- drag-and-drop files onto the widget or use the file picker button to browse local files
3. **Upload with progress** -- files upload automatically with real-time progress bars. Binary files use chunked uploads (create-session, stage-blob, chunk, finalize). Text files use single-step text-file upload. Web URLs use web-import
4. **Reference in chat** -- after upload completes, click "Reference in Chat" to attach the uploaded files to the agent conversation for further discussion or AI analysis
The widget uses the `upload` tool (actions: create-session, chunk, finalize, stage-blob, text-file, web-import, status, cancel, limits, extensions) and the `storage` tool (action: list) via the MCP bridge.
**Launch via prompt:** Use the `App: Upload Files` prompt in desktop MCP clients.
**Launch via tool:**
```
apps action launch app_id uploader context_type workspace context_id <workspace_id>
```
### Using the Apps Tool
The `apps` tool provides widget discovery and launching:
1. **List apps:** `apps` action `list` -- returns all available widgets with metadata
2. **App details:** `apps` action `details` with `app_id` -- full metadata for a specific widget
3. **Launch app:** `apps` action `launch` with `app_id`, `context_type`, `context_id` -- opens widget with context
4. **Find apps for a tool:** `apps` action `get-tool-apps` with `tool_name` -- maps tools to their widgets
### Widget Context
All widgets accept workspace or share context:
- `context_type: "workspace"` + `context_id: "<workspace_id>"`
- `context_type: "share"` + `context_id: "<share_id>"`
### Design System
Widgets use a shared design system matching the Fast.io frontend:
- Light and dark mode support (follows system preference or explicit `data-theme` attribute)
- Consistent typography, spacing, colors, and icons derived from the frontend theme
- Responsive layout (desktop, tablet, mobile breakpoints)
### Example: Launch File Picker
```
apps action launch app_id file-picker context_type workspace context_id <workspace_id>
```
### Example: Find Widgets for Storage Operations
```
apps action get-tool-apps tool_name storage
```
---
## 9. Complete Tool Reference
All 19 tools with their actions organized by functional area. Each entry shows the action name and its description. Workflow tools (task, worklog, approval, todo) require workflow to be enabled on the target workspace or share.
### auth
**signin** -- Sign in to Fast.io with email and password. Returns a JWT auth token. If the account has 2FA enabled the token will have limited scope until 2fa-verify is called. The token is stored in the session automatically.
**set-api-key** -- Authenticate using a Fast.io API key. API keys work as Bearer tokens and by default have the same permissions as the account owner. Scoped keys restrict access to specific entities (same scope system as OAuth tokens). The key is validated against the API and stored in the session. All subsequent tool calls are authenticated automatically. Unscoped API keys do not expire unless revoked; scoped keys may have an optional expiration.
**signup** -- Create a new Fast.io agent account (agent=true), then automatically sign in. Sets account_type to "agent" and assigns the free agent plan. Email verification is required after signup -- call email-verify to send a code, then call it again with the code to verify. Most endpoints require a verified email. No authentication required for signup itself.
**check** -- Check whether the current session token is still valid. Returns the user ID associated with the token.
**session** -- Get current session information for the authenticated user, including profile details such as name, email, and account flags.
**signout** -- Sign out by clearing the stored session. If currently authenticated the token is verified first.
**2fa-verify** -- Complete two-factor authentication by submitting a 2FA code. Call this after signin returns two_factor_required: true. The new full-scope token is stored automatically.
**email-check** -- Check if an email address is available for registration. No authentication required.
**password-reset-request** -- Request a password reset email. Always returns success for security (does not reveal whether the email exists). No authentication required.
**password-reset** -- Set a new password using a reset code received by email. No authentication required.
**email-verify** -- Send or validate an email verification code. When email_token is omitted a new code is sent. When provided the code is validated and the email marked as verified.
**status** -- Check local session status. No API call is made. Returns whether the user is authenticated, and if so their user_id, email, token expiry, scopes (raw string), scopes_detail (hydrated array with entity names, domains, and parent hierarchy -- or null if not yet fetched), and agent_name (if set).
**pkce-login** -- Start a browser-based PKCE login flow. Returns a URL for the user to open in their browser. After signing in and approving access, the browser displays an authorization code. The user copies the code and provides it to pkce-complete to finish signing in. No password is sent through the agent. Optional params: `scope_type` (default `"user"` for full access; use `"org"`, `"workspace"`, `"all_orgs"`, `"all_workspaces"`, or `"all_shares"` for scoped access), `agent_name` (displayed in the approval screen and audit logs; defaults to MCP client name).
**pkce-complete** -- Complete a PKCE login flow by exchanging the authorization code for an access token. Call this after the user has approved access in the browser and copied the code from the screen. The token is stored in the session automatically. If scoped access was granted, the response includes `scopes` (JSON array of granted scope strings like `"org:123:rw"`) and `agent_name`.
**api-key-create** -- Create a new persistent API key. The full key value is only returned once at creation time -- store it securely. Optional parameters: `name` (memo/label), `scopes` (JSON array of scope strings like `["org:123:rw", "workspace:456:r"]` for restricted access -- omit for full access), `agent_name` (agent/application name, max 128 chars), `key_expires` (ISO 8601 expiration datetime -- omit for no expiration), `token` (2FA code -- required when account has 2FA enabled, not needed with API key auth). Scoped keys use the same scope system as v2.0 JWT tokens.
**api-key-update** -- Update an existing API key's metadata. Requires `key_id`. Optional parameters: `name` (memo/label), `scopes` (JSON scope array -- send empty string to clear and restore full access), `agent_name` (send empty string to clear), `key_expires` (send empty string to clear expiration). Only specified fields are updated.
**api-key-list** -- List all API keys for the authenticated user. Key values are masked (only last 4 characters visible). Responses include `scopes`, `agent_name`, and `expires` fields for each key.
**api-key-get** -- Get details of a specific API key. The key value is masked. Response includes `scopes`, `agent_name`, and `expires` fields.
**api-key-delete** -- Revoke (delete) an API key. This action cannot be undone. Optional parameter: `token` (2FA code -- required when account has 2FA enabled, not needed with API key auth).
**2fa-status** -- Get the current two-factor authentication configuration status (enabled, unverified, or disabled).
**2fa-enable** -- Enable two-factor authentication on the specified channel. For TOTP, returns a binding URI for QR code display. The account enters an 'unverified' state until 2fa-verify-setup is called.
**2fa-disable** -- Disable (remove) two-factor authentication from the account. Requires a valid 2FA code to confirm when 2FA is in the enabled (verified) state.
**2fa-send** -- Send a 2FA verification code to the user's phone via SMS, voice call, or WhatsApp.
**2fa-verify-setup** -- Verify a 2FA setup code to confirm enrollment. Transitions 2FA from the 'unverified' state to 'enabled'.
**oauth-list** -- List all active OAuth sessions for the authenticated user.
**oauth-details** -- Get details of a specific OAuth session.
**oauth-revoke** -- Revoke a specific OAuth session (log out that device).
**oauth-revoke-all** -- Revoke all OAuth sessions. Optionally exclude the current session to enable 'log out everywhere else'.
### user
**me** -- Get the current authenticated user's profile details.
**update** -- Update the current user's profile (name, email, etc.).
**search** -- Search for users by name or email address.
**close** -- Close/delete the current user account (requires email confirmation).
**details-by-id** -- Get another user's public profile details by their user ID.
**profiles** -- Check what profile types (orgs, workspaces, shares) the user has access to.
**allowed** -- Check if the user's country allows creating shares and organizations.
**org-limits** -- Get free org creation eligibility, limits, and cooldown status.
**list-shares** -- List all shares the current user is a member of.
**invitation-list** -- List all pending invitations for the current user.
**invitation-details** -- Get details of a specific invitation by its ID or key.
**accept-all-invitations** -- Accept all pending invitations at once.
**asset-upload** -- Upload a user asset (e.g. profile photo). Provide either plain-text content or base64-encoded content_base64 (not both).
**asset-delete** -- Delete a user asset (e.g. profile photo).
**asset-types** -- List available asset types for users.
**asset-list** -- List all user assets.
### org
**list** -- List internal organizations (orgs the user is a direct member of, `member: true`). Each org includes `web_url`. Returns member orgs with subscription status, user permission, and plan info. Non-admin members only see orgs with active subscriptions. Does not include external orgs -- use discover-external for those.
**details** -- Get detailed information about an organization. Returns `web_url`. Fields returned vary by the caller's role: owners see encryption keys and storage config, admins see billing and permissions, members see basic info.
**members** -- List all members of an organization with their IDs, emails, names, and permission levels.
**invite-member** -- Invite a user to the organization by email. The email is passed in the URL path (not the body). If the user already has a Fast.io account they are added directly; otherwise an email invitation is sent. Cannot add as owner.
**remove-member** -- Remove a member from the organization. Requires member management permission as configured by the org's perm_member_manage setting.
**update-member-role** -- Update a member's role/permissions in the organization. Cannot set role to 'owner' -- use transfer-ownership instead.
**limits** -- Get organization plan limits and credit usage. Returns credit limits, usage stats, billing period, trial info, and run-rate projections. Requires admin or owner role.
**list-workspaces** -- List workspaces in an organization that the current user can access. Each workspace includes `web_url`. Owners and admins see all workspaces; members see workspaces matching the join permission setting.
**list-shares** -- List shares accessible to the current user. Each share includes `web_url`. Returns all shares including parent org and workspace info. Use parent_org in the response to identify shares belonging to a specific organization.
**create** -- Create a new organization on the "agent" billing plan. Requires `domain` (2-63 chars, lowercase alphanumeric + hyphens) and `name` (3-100 chars, no control characters). The authenticated user becomes the owner. A storage instance and agent-plan subscription (free, 50 GB, 5,000 credits/month) are created automatically. Returns the new org and trial status.
**update** -- Update organization details. Returns `web_url`. Only provided fields are changed. Supports identity, branding, social links, permissions, and billing email. Requires admin or owner role.
**close** -- Close/delete an organization. Cancels any active subscription and initiates deletion. Requires owner role. The confirm field must match the org domain or org ID.
**public-details** -- Get public details for an organization. Returns `web_url`. Does not require membership -- returns public-level fields only (name, domain, logo, accent color). The org must exist and not be closed/suspended.
**create-workspace** -- Create a new workspace within the organization. Returns `web_url`. Checks workspace feature availability and creation limits based on the org billing plan. The creating user becomes the workspace owner. **Namespace:** Workspace `folder_name` is globally unique across the platform. If the requested name is already taken and does not contain a dash, the server automatically prefixes it with the org ID (e.g. `reports` → `3587676312889739297-reports`). Names with dashes are sent as-is. The final `folder_name` is returned in the response.
**billing-plans** -- List available billing plans with pricing, features, and plan defaults. Returns plan IDs needed for subscription creation.
**billing-create** -- Create a new subscription or update an existing one. For new subscriptions, creates a Stripe Setup Intent. For existing subscriptions, updates the plan. Requires admin or owner.
**billing-cancel** -- Cancel the organization's subscription. Requires owner role. Some plans may cause the org to be closed on cancellation.
**billing-details** -- Get comprehensive billing and subscription details including Stripe customer info, subscription status, setup intents, payment intents, and plan info. Requires admin or owner.
**billing-activate** -- Activate a billing plan (development environment only). Simulates Stripe payment setup and activates the subscription using a test payment method.
**billing-reset** -- Reset billing status (development environment only). Deletes the Stripe customer and removes the subscriber flag.
**billing-members** -- List billable members with their workspace memberships. Shows who the org is being billed for. Requires admin or owner role.
**billing-meters** -- Get usage meter time-series data (storage, transfer, AI, etc). Returns grouped data points with cost and credit calculations. Requires admin or owner role.
**leave** -- Leave an organization. Removes the current user's own membership. Owners cannot leave -- they must transfer ownership or close the org first.
**member-details** -- Get detailed membership information for a specific user in the organization, including permissions, invite status, notification preference, and expiration.
**transfer-ownership** -- Transfer organization ownership to another member. The current owner is demoted to admin. Requires owner role.
**transfer-token-create** -- Create a transfer token (valid 72 hours) for an organization. Send the claim URL `https://go.fast.io/claim?token=<token>` to a human. Use when handing off an org or when hitting 402 Payment Required on the agent plan. Requires owner role.
**transfer-token-list** -- List all active transfer tokens for an organization. Each token includes `web_url` (claim URL). Requires owner role.
**transfer-token-delete** -- Delete (revoke) a pending transfer token. Requires owner role.
**transfer-claim** -- Claim an organization using a transfer token. The authenticated user becomes the new owner and the previous owner is demoted to admin.
**invitations-list** -- List all pending invitations for the organization. Optionally filter by invitation state. Requires any org membership.
**invitation-update** -- Update an existing invitation for the organization. Can change state, permissions, or expiration.
**invitation-delete** -- Revoke/delete an invitation for the organization.
**join** -- Join an organization via invitation or authorized domain auto-join. Optionally provide an invitation key and action (accept/decline).
**asset-upload** -- Upload an org asset (e.g. logo, banner). Provide either plain-text content or base64-encoded file_base64 (not both). Requires admin or owner role.
**asset-delete** -- Delete an asset from the organization. Requires admin or owner role.
**asset-types** -- List available asset types for organizations.
**asset-list** -- List all organization assets.
**discover-all** -- List all accessible organizations (joined + invited). Each org includes `web_url`. Returns org data with user_status indicating relationship.
**discover-available** -- List organizations available to join. Each org includes `web_url`. Excludes orgs the user is already a member of.
**discover-check-domain** -- Check if an organization domain name is available for use. Validates format, checks reserved names, and checks existing domains.
**discover-external** -- List external organizations (`member: false`). Each org includes `web_url`. Orgs the user can access only through workspace membership, not as a direct org member. Common when a human invites an agent to a workspace without inviting them to the org. See **Internal vs External Orgs** in the Organizations section.
### workspace
**list** -- List all workspaces the user has access to across all organizations. Each workspace includes `web_url`.
**details** -- Get detailed information about a specific workspace. Returns `web_url`.
**update** -- Update workspace settings such as name, description, branding, and permissions. Returns `web_url`.
**delete** -- Permanently close (soft-delete) a workspace. Requires Owner permission and confirmation.
**archive** -- Archive a workspace (blocks modifications, preserves data). Requires Admin+.
**unarchive** -- Restore an archived workspace to active status. Requires Admin+.
**members** -- List all members of a workspace with their roles and status.
**list-shares** -- List all shares within a workspace, optionally filtered by archive status. Each share includes `web_url`.
**import-share** -- Import a user-owned share into a workspace. You must be the sole owner of the share.
**available** -- List workspaces the current user can join but has not yet joined. Each workspace includes `web_url`.
**check-name** -- Check if a workspace folder name is available for use. Workspace names are globally unique. Pass optional `check_org_id` to get an org-ID-prefixed alternative suggestion (e.g. `3587676312889739297-reports`) if the name is taken.
**create-note** -- Create a new markdown note in workspace storage. Returns `web_url` (note preview link).
**update-note** -- Update a note's markdown content and/or name (at least one required). Returns `web_url` (note preview link).
**read-note** -- Read a note's markdown content and metadata. Returns the note content and `web_url` (note preview link).
**quickshare-get** -- Get existing quickshare details for a node. Returns `web_url`.
**quickshare-delete** -- Revoke and delete a quickshare link for a node.
**quickshares-list** -- List all active quickshares in the workspace. Each quickshare includes `web_url`.
**metadata-template-create** -- Create a new metadata template in the workspace. Requires name, description, category (legal, financial, business, medical, technical, engineering, insurance, educational, multimedia, hr), and fields (JSON-encoded array of field definitions). Each field has name, description, type (string, int, float, bool, json, url, datetime), and optional constraints (min, max, default, fixed_list, can_be_null).
**metadata-template-delete** -- Delete a metadata template. System templates and locked templates cannot be deleted. Requires template_id.
**metadata-template-list** -- List metadata templates. Optional template_filter: enabled, disabled, custom (non-system), or system. Returns all non-deleted templates when no filter is specified.
**metadata-template-details** -- Get full details of a metadata template including all field definitions. Requires template_id.
**metadata-template-update** -- Update an existing metadata template. Any combination of name, description, category, and fields can be updated. Requires template_id.
**metadata-template-clone** -- Clone a metadata template with optional modifications. Creates a new template based on an existing one. Same parameters as metadata-template-update. Requires template_id.
**metadata-template-assign** -- Assign a metadata template to a workspace. Each workspace can have at most one assigned template. Assigning a system template automatically clones it. Requires template_id. Optional node_id (null for workspace-level assignment).
**metadata-template-unassign** -- Remove the template assignment from a workspace. Requires workspace admin permission.
**metadata-template-resolve** -- Resolve which metadata template applies to a given node. Returns the workspace-level template (node_id is accepted but currently inherits from workspace). Returns null if no template is assigned.
**metadata-template-assignments** -- List all template assignments in the workspace.
**metadata-get** -- Get all metadata for a file, including both template-conforming metadata and custom (freeform) key-value pairs. Returns node details, template_id, template_metadata array, and custom_metadata array. Requires node_id.
**metadata-set** -- Set or update metadata key-value pairs on a file. Values must conform to the template field definitions. Requires node_id, template_id, and key_values (JSON object of key-value pairs).
**metadata-delete** -- Delete metadata from a file. Provide keys (JSON array of key names) to delete specific entries, or omit to delete all metadata. Only works on files and notes, not folders. Requires node_id.
**metadata-extract** -- Trigger AI-powered metadata extraction from a file. The AI analyzes file content and populates metadata fields according to the template. Extracted values are marked with is_auto: true. Consumes AI credits. Optional template_id (defaults to workspace template). Requires node_id.
**metadata-list-files** -- List files that have metadata for a specific template, with optional filtering and sorting. Requires node_id (folder to search in) and template_id. Optional metadata_filters (JSON-encoded), order_by (field key), and order_desc.
**metadata-list-templates-in-use** -- List which metadata templates are in use within a folder, with usage counts per template. Requires node_id.
**metadata-versions** -- Get metadata version history for a file. Returns snapshots of metadata changes over time. Requires node_id.
**enable-workflow** -- Enable workflow features (tasks, worklogs, approvals, todos) on a workspace. Must be called before using workflow tools on the workspace.
**disable-workflow** -- Disable workflow features on a workspace. All workflow data is preserved but inaccessible until re-enabled.
### share
**list** -- List shares the authenticated user has access to. Each share includes `web_url`.
**details** -- Get full details of a specific share. Returns `web_url`.
**create** -- Create a new share in a workspace.
**update** -- Update share settings (partial update).
**delete** -- Delete (close) a share. Requires the share ID or custom name as confirmation.
**public-details** -- Get public-facing share info (no membership required, just auth).
**archive** -- Archive a share. Blocks guest access and restricts modifications.
**unarchive** -- Restore a previously archived share to active status.
**password-auth** -- Authenticate with a share password. Returns a scoped JWT for the share.
**members** -- List all members of a share.
**available** -- List shares available to join (joined and owned, excludes pending invitations). Each share includes `web_url`.
**check-name** -- Check if a share custom name (URL name) is available.
**quickshare-create** -- Create a temporary QuickShare link for a file in a workspace. Optional `expires` (seconds, default 10,800, max 604,800 = 7 days) or `expires_at` (ISO 8601 datetime).
**enable-workflow** -- Enable workflow features (tasks, worklogs, approvals, todos) on a share. Must be called before using workflow tools on the share.
**disable-workflow** -- Disable workflow features on a share. All workflow data is preserved but inaccessible until re-enabled.
### storage
All storage actions require `context_type` parameter (`workspace` or `share`) and `context_id` (the 19-digit profile ID).
**list** -- List files and folders in a directory with pagination. Each item includes `web_url` (workspace only). Requires `context_type`, `context_id`, and `node_id` (use `root` for root folder).
**recent** -- List recently modified files and folders across all directories, sorted by updated descending. Unlike `list` which is scoped to a single folder, this returns nodes from the entire storage tree. Supports optional `type` filter (`file`, `folder`, `link`, `note`), `page_size` (100, 250, or 500), and `cursor` for pagination. For workspace folder shares, results are automatically filtered to the share's subtree.
**details** -- Get full details of a specific file or folder. Returns `web_url` (human-friendly link to the file preview or folder in the web UI, workspace only).
**search** -- Search for files by keyword or semantic query. Each result includes `web_url` (workspace only).
**trash-list** -- List items currently in the trash. Each item includes `web_url` (workspace only).
**create-folder** -- Create a new folder. Returns `web_url` (workspace only).
**copy** -- Copy files/folders. Single copy via `node_id` (workspace or share). Bulk copy via `node_ids` array (workspace only). Returns `web_url` on the new copy (workspace only).
**move** -- Move files/folders. Single move via `node_id` (workspace or share). Bulk move via `node_ids` array (workspace only). Returns `web_url` (workspace only).
**delete** -- Delete files/folders by moving them to the trash. Single delete via `node_id` (workspace or share). Bulk delete via `node_ids` array (workspace only).
**rename** -- Rename a file or folder. Returns `web_url` (workspace only).
**purge** -- Permanently delete a trashed node (irreversible). Requires Member permission.
**restore** -- Restore files/folders from the trash. Single restore via `node_id` (workspace or share). Bulk restore via `node_ids` array (workspace only). Returns `web_url` on the restored node (workspace only).
**add-file** -- Link a completed upload to a storage location. Returns `web_url` (workspace only).
**add-link** -- Add a share reference link node to storage.
**transfer** -- Copy or move a node to another workspace or share storage instance. Default mode is 'copy' (keeps source). Use transfer_mode='move' to copy then trash the source (cannot move root). When mode=move, response includes source_trashed (boolean) indicating whether the source was successfully trashed.
**version-list** -- List version history for a file. Returns `web_url` for the file (workspace only).
**version-restore** -- Restore a file to a previous version. Returns `web_url` for the file (workspace only).
**lock-acquire** -- Acquire an exclusive lock on a file to prevent concurrent edits.
**lock-status** -- Check the lock status of a file.
**lock-release** -- Release an exclusive lock on a file.
**preview-url** -- Get a preauthorized preview URL for a file (thumbnail, PDF, image, video, audio, spreadsheet). Requires `preview_type` parameter. Returns `preview_url` (ready-to-use URL) and `web_url` (human-friendly link to the file in the web UI, workspace only).
**preview-transform** -- Request a file transformation (image resize, crop, format conversion) and get a download URL for the result. Requires `transform_name` parameter. Returns `transform_url` (ready-to-use URL) and `web_url` (human-friendly link to the file in the web UI, workspace only).
### upload
**create-session** -- Create a chunked upload session for a file.
**chunk** -- Upload a single chunk. Use `content` for text/strings, `data` for base64-encoded binary, or `blob_ref` for binary staged via `stage-blob` action or `POST /blob`. Provide exactly one.
**finalize** -- Finalize an upload session, trigger file assembly, and poll until fully stored or failed. Returns the final session state.
**status** -- Get the current status of an upload session. Supports server-side long-poll via optional `wait` parameter (in milliseconds, 0 = immediate).
**cancel** -- Cancel and delete an active upload session.
**list-sessions** -- List all active upload sessions for the current user.
**cancel-all** -- Cancel and delete ALL active upload sessions at once.
**chunk-status** -- Get chunk information for an upload session.
**chunk-delete** -- Delete/reset a chunk in an upload session.
**stage-blob** -- Stage base64-encoded binary data as a blob for later use with the `chunk` action's `blob_ref` parameter. Pass `data` (base64 string). Returns `{ blob_id, size }`. Blobs expire after 5 minutes and are consumed on first use. Alternative to passing `data` directly in the chunk call.
**text-file** -- Upload a text file in a single step using the Fast.io single-request upload pattern. Sends the file in one multipart POST and returns the new file ID directly. Use for text-based files (code, markdown, CSV, JSON, config) instead of the multi-step chunked flow.
**web-import** -- Import a file from an external URL into a workspace or share.
**web-list** -- List the user's web upload jobs with optional filtering.
**web-cancel** -- Cancel an active web upload job.
**web-status** -- Get detailed status of a specific web upload job.
**limits** -- Get upload size and chunk limits for the user's plan.
**extensions** -- Get restricted and allowed file extensions for uploads.
### download
**file-url** -- Get a download token and URL for a file. Optionally specify a version. Requires `context_type`, `context_id`, and `node_id`.
**zip-url** -- Get a ZIP download URL for a folder or entire workspace/share. Returns the URL with auth instructions. Requires `context_type`, `context_id`, and `node_id` (use `root` for entire storage tree).
**quickshare-details** -- Get metadata and download info for a quickshare link. No authentication required.
### ai
All AI actions require `context_type` parameter (`workspace` or `share`) and `context_id` (the 19-digit profile ID).
**chat-create** -- Create a new AI chat with an initial question. Default scope is the entire workspace (all indexed documents) — omit `files_scope` and `folders_scope` unless you need to narrow the search. When using scope or attachments, provide `nodeId:versionId` pairs — versionId is auto-resolved to the current version if left empty (get explicit `versionId` from storage list/details `version` field). When using `files_attach`, verify `ai.attach` is `true` for each file first (check via storage details). Type is auto-promoted from `chat` to `chat_with_files` when file parameters are present. Returns chat ID and initial message ID -- use message-read to get the AI response.
**chat-list** -- List AI chats.
**chat-details** -- Get AI chat details including full message history.
**chat-update** -- Update the name of an AI chat.
**chat-delete** -- Delete an AI chat.
**chat-publish** -- Publish a private AI chat, making it visible to all members.
**message-send** -- Send a follow-up message in an existing AI chat. Returns message ID -- use message-read to get the AI response.
**message-list** -- List all messages in an AI chat.
**message-details** -- Get details for a specific message in an AI chat including response text and citations.
**message-read** -- Read an AI message response. Polls the message details endpoint until the AI response is complete, then returns the full text.
**search** -- Semantic search across indexed documents and code. Returns ranked document chunks with relevance scores -- faster and lighter than AI chat (stateless GET, no LLM inference). Requires Intelligence ON. Params: `query_text` (2-1,000 chars), optional `files_scope`, `folders_scope` (same format as chat scoping), `limit` (1-500, default 100), `offset`. Results include content snippets, scores, and source file details with `web_url` (workspace only). Use search to find relevant documents, then chat to ask questions about them.
**share-generate** -- Generate AI Share markdown with temporary download URLs for files that can be pasted into external AI chatbots.
**transactions** -- List AI token usage transactions for billing tracking.
**autotitle** -- Generate AI-powered title and description based on contents (share context only).
### comment
All comment endpoints use the path pattern `/comments/{entity_type}/{parent_id}/` or `/comments/{entity_type}/{parent_id}/{node_id}/` where `entity_type` is `workspace` or `share`, `parent_id` is the 19-digit profile ID, and `node_id` is the file's opaque ID.
**list** -- List comments on a specific file (node). Params: sort (`created`/`-created`), limit (2-200), offset, include_deleted, reference_type filter, include_total.
**list-all** -- List all comments across a workspace or share (not node-specific). Same listing params as list.
**add** -- Add a comment to a specific file. Body: text (max 8,192 chars total, max 2,048 chars display text with `@[...]` mention tags stripped). Supports mention tags: `@[profile:id]`, `@[user:opaqueId:Name]`, `@[file:fileId:name.ext]`. Optional parent_comment_id (single-level threading, replies to replies auto-flatten), optional reference (type, timestamp, page, region, text_snippet for content anchoring; exact, prefix, suffix, start_offset, end_offset for text anchoring on markdown/notes -- use type `"document"` or `"text"`), optional linked_entity_type (`task` or `approval`) and linked_entity_id to link the comment to a workflow entity at creation time. Uses JSON body.
**delete** -- Delete a comment. Recursive: deleting a parent also removes all its replies.
**bulk-delete** -- Bulk soft-delete multiple comments (max 100). NOT recursive: replies to deleted comments are preserved.
**details** -- Get full details of a single comment by its ID. Response includes `linked_entity_type` and `linked_entity_id` (null when not linked).
**reaction-add** -- Add or change your emoji reaction. One reaction per user per comment; new replaces previous.
**reaction-remove** -- Remove your emoji reaction from a comment.
**link** -- Link an existing comment to a workflow entity. Params: comment_id, linked_entity_type (`task` or `approval`), linked_entity_id. One link per comment; linking replaces any existing link. Returns the updated comment with linked fields populated.
**unlink** -- Remove the workflow link from a comment. Params: comment_id. Returns the updated comment with linked fields set to null.
**linked** -- Reverse lookup: find all comments linked to a given workflow entity. Params: linked_entity_type (`task` or `approval`), linked_entity_id. Returns a list of comments linked to the specified entity.
### event
**search** -- Search the audit/event log with filters for profile, event type, category, subcategory, event name, and date range. See **Event Filtering Reference** in section 7 for the full taxonomy of categories, subcategories, and event names.
**summarize** -- Search events and return an AI-powered natural language summary of the activity. Accepts the same category/subcategory/event filters as search.
**details** -- Get full details for a single event by its ID.
**activity-list** -- Poll for recent activity events on a workspace or share.
**activity-poll** -- Long-poll for activity changes on a workspace or share. The server holds the connection until a change occurs or the wait period expires. Returns activity keys indicating what changed and a lastactivity timestamp for the next poll.
### member
All member actions require `entity_type` parameter (`workspace` or `share`) and `entity_id` (the 19-digit profile ID).
**add** -- Add an existing user by user ID, or invite by email. Pass the email address or user ID as `email_or_user_id`. For workspaces, set access level with `permissions` (admin/member/guest). For shares, use `role` (admin/member/guest/view).
**remove** -- Remove a member (cannot remove the owner).
**details** -- Get detailed membership info for a specific member. For workspaces, pass `member_id`; for shares, pass `user_id`.
**update** -- Update a member's role, notifications, or expiration.
**transfer-ownership** -- Transfer ownership to another member (current owner is demoted to admin).
**leave** -- Leave (remove yourself). Owner must transfer ownership first.
**join** -- Self-join based on organization membership.
**join-invitation** -- Accept or decline an invitation using an invitation key.
### invitation
All invitation actions require `entity_type` parameter (`workspace` or `share`) and `entity_id` (the 19-digit profile ID).
**list** -- List all pending invitations.
**list-by-state** -- List invitations filtered by state.
**update** -- Resend or update an invitation (by ID or invitee email).
**delete** -- Revoke and delete a pending invitation.
### asset
All asset actions require `entity_type` parameter (`org`, `workspace`, `share`, or `user`) and `entity_id` (the 19-digit profile ID for org/workspace/share).
**upload** -- Upload an asset (e.g. logo, banner, profile photo). Provide either plain-text content or base64-encoded data (not both).
**delete** -- Delete an asset.
**types** -- List available asset types for the entity.
**list** -- List all assets for the entity.
**read** -- Read/download an asset.
### task
Task list and task management for workspaces and shares. All task actions require workflow to be enabled on the target entity (`workspace` action `enable-workflow` or `share` action `enable-workflow`).
**list-lists** -- List all task lists for a workspace or share. Requires `profile_type` and `profile_id`. Supports `sort_by` (created, updated, name), `sort_dir`, `limit` (1-200), `offset`, and `format` ("md" for markdown).
**create-list** -- Create a new task list. Requires `profile_type`, `profile_id`, and `name` (1-255 chars). Optional `description` (max 2000 chars).
**list-details** -- Get details of a specific task list. Requires `list_id`. Supports `format`.
**update-list** -- Update a task list's name or description. Requires `list_id`. Optional `name`, `description`.
**delete-list** -- Soft-delete a task list and all its tasks. Requires `list_id`. Destructive.
**list-tasks** -- List tasks in a task list. Requires `list_id`. Supports `status` filter, `assignee` filter, `sort_by` (created, updated, name, priority, status), `sort_dir`, `limit` (1-200), `offset`, and `format`.
**create-task** -- Create a new task in a list. Requires `list_id` and `title` (1-500 chars). Optional `description` (max 5000 chars), `status` (pending, in_progress, complete, blocked), `priority` (0=none, 1=low, 2=medium, 3=high, 4=critical), `assignee_id` (profile ID), `dependencies` (array of task IDs), `node_id` (link to file/folder/note).
**task-details** -- Get full details of a specific task. Requires `list_id` and `task_id`. Supports `format`.
**update-task** -- Update a task's title, description, status, priority, assignee, dependencies, or node link. Requires `list_id` and `task_id`.
**delete-task** -- Soft-delete a task. Requires `list_id` and `task_id`. Destructive.
**change-status** -- Change a task's status. Requires `list_id`, `task_id`, and `status`.
**assign-task** -- Assign or unassign a task. Requires `list_id` and `task_id`. Pass `assignee_id` (profile ID) to assign, or null/omit to unassign.
**bulk-status** -- Change status on multiple tasks at once. Requires `list_id`, `task_ids` (array of task IDs, max 100), and `status`.
**move-task** -- Move a task from one list to another within the same profile. Requires `list_id` (source list), `task_id`, and `target_task_list_id` (destination list). Optional `sort_order` (position in target list, default 0). Source and target lists must belong to the same profile. Returns the updated task with `old_task_list_id` and `new_task_list_id`.
**reorder-tasks** -- Reorder tasks within a list. Requires `list_id` and `task_ids` (array of task IDs in the desired display order). The server converts this to `{order: [{id, sort_order}, ...]}` for the API.
**reorder-lists** -- Reorder task lists within a workspace or share. Requires `profile_type`, `profile_id`, and `list_ids` (array of task list IDs in the desired display order). The server converts this to `{order: [{id, sort_order}, ...]}` for the API.
### worklog
Activity log for tracking agent work. After uploads, task changes, share creation, or any significant action, log what you did and why — builds a searchable audit trail for humans and AI. All worklog actions require workflow to be enabled on the target entity.
**append** -- Append a new entry to the worklog. Requires `entity_type` ("task", "task_list", "node", or "profile"), `entity_id`, and `content` (1-10000 chars). Use after making changes to record what was done and why. Entries are immutable after creation.
**list** -- List worklog entries. Requires `entity_type` ("task", "task_list", "node", or "profile") and `entity_id` (the corresponding entity's opaque ID, or profile 19-digit ID for entity_type "profile"). Supports `type` filter ("entry" or "interjection"), `sort_dir` ("asc" or "desc", default "desc"), `limit` (1-200), `offset`, and `format` ("md" for markdown).
**interject** -- Create an urgent interjection entry that requires acknowledgement. Requires `entity_type` ("task", "task_list", "node", or "profile"), `entity_id`, and `content` (1-10000 chars). Interjections are priority corrections -- always treated as urgent.
**details** -- Get full details of a specific worklog entry. Requires `entry_id`. Supports `format`.
**acknowledge** -- Acknowledge an interjection entry, marking it as seen. Requires `entry_id`. Only entries with `acknowledgable: true` can be acknowledged.
**unacknowledged** -- List unacknowledged interjections (entries where `acknowledgable` is `true`). Requires `entity_type` ("task", "task_list", "node", or "profile") and `entity_id`. Supports `limit`, `offset`, and `format`. Always check for unacknowledged interjections before proceeding with work.
### approval
Formal approval requests scoped to tasks, storage nodes, or worklog entries. All approval actions require workflow to be enabled on the target entity.
**list** -- List approval requests for a workspace or share. Requires `profile_type` and `profile_id`. Supports `status` filter (pending, approved, rejected), `limit` (1-200, default 100), `offset`, and `format`.
**create** -- Create a new approval request. Requires `entity_type` ("task", "node", or "worklog_entry"), `entity_id`, `profile_id`, and `description` (1-5000 chars). Optional `approver_id` (profile ID of designated approver), `deadline` (ISO 8601), `node_id` (artifact reference).
**details** -- Get full details of an approval request including approver list and resolution. Requires `approval_id` (opaque alphanumeric). Supports `format`.
**resolve** -- Resolve an approval request. Requires `approval_id` and `resolve_action` ("approve" or "reject"). Optional `comment` (max 5000 chars). Only designated approvers can resolve.
### todo
Simple flat checklists scoped to workspaces and shares. No nesting. All todo actions require workflow to be enabled on the target entity.
**list** -- List todos for a workspace or share. Requires `profile_type` and `profile_id`. Supports `filter_done` (boolean), `sort_by` (created, updated, title), `sort_dir`, `limit` (1-200, default 50), `offset`, and `format`.
**create** -- Create a new todo item. Requires `profile_type`, `profile_id`, and `title` (1-500 chars). Optional `assignee_id`.
**details** -- Get full details of a todo. Requires `todo_id` (opaque alphanumeric). Supports `format`.
**update** -- Update a todo. Requires `todo_id`. Supports `title`, `assignee_id`, `done`.
**delete** -- Soft-delete a todo. Requires `todo_id`. Destructive.
**toggle** -- Toggle the done state of a todo. Requires `todo_id`. Flips between done and not done.
**bulk-toggle** -- Set done state on multiple todos at once. Requires `profile_type`, `profile_id`, `todo_ids` (array of todo IDs, max 100), and `done` (boolean: true to mark done, false to mark not done).
### apps
Interactive MCP App widget discovery and launching. Widgets are interactive HTML5 UIs that render in agent conversations.
**list** -- List all available MCP App widgets with their metadata (title, description, supported tools, supported actions, resource URI).
**details** -- Get full metadata for a specific widget. Requires `app_id` (the widget name, e.g., "file-picker").
**launch** -- Launch a widget with workspace or share context. Requires `app_id`, `context_type` ("workspace" or "share"), and `context_id` (the 19-digit profile ID). Returns the widget HTML content ready for rendering.
**get-tool-apps** -- Find widgets associated with a specific tool domain. Requires `tool_name` (e.g., "storage", "ai", "comment"). Returns widgets that provide UI for that tool's operations.
---
## 10. Code Mode (Headless Agents)
When connecting from a headless agent (Claude Code, Cursor, Continue, etc.), the server automatically enables Code Mode -- a lightweight alternative to the full 19-tool set. Code Mode exposes 4 tools total:
| Tool | Purpose |
|------|---------|
| `auth` | Authentication (signin, signup, API keys, PKCE, 2FA) |
| `upload` | File uploads (chunked, text, web-import) |
| `search` | Discover API endpoints by keyword, tag, or concept |
| `execute` | Make authenticated API calls to Fast.io |
Clients with MCP Apps support (Claude Desktop, Cline) continue to receive the full 19-tool set plus 12 app-* widget tools. Unknown clients default to the full tool set.
### search Tool
Query the API spec by keywords, paths, or concepts. Returns matching endpoints with method, path, parameters, and descriptions.
```
search query="list files in workspace" tag="storage"
search query="create share" tag="share"
search query="authentication"
search query="pagination" include_concepts=true
```
Parameters:
- `query` (string, required) -- Keywords, endpoint paths, or concepts to search for
- `tag` (string, optional) -- Filter by domain: auth, workspace, storage, ai, share, upload, org, user, member, comment, event, metadata, etc.
- `include_concepts` (boolean, optional) -- Include concept docs (pagination, IDs, errors). Default true.
### execute Tool
Make authenticated API calls to the Fast.io REST API. Use `search` first to discover endpoints.
Methods:
- `get` -- GET request with optional query parameters
- `post` -- POST with form-encoded body (default API format)
- `postJson` -- POST with JSON body
- `delete` -- DELETE request
- `put` -- PUT with form-encoded body
The auth token is injected automatically. Path parameters must be filled by the caller (replace `{workspace_id}` with the actual ID). For multi-step operations, make multiple sequential execute calls.
```
execute method="get" path="/org/1234567890123456789/list/workspaces/"
```
```
execute method="post" path="/workspace/1234567890123456789/storage/root/createfolder/" body={"name": "reports"}
```
```
execute method="postJson" path="/workspace/1234567890123456789/storage/root/createnote/" body={"name": "summary.md", "content": "# Summary"}
```
Parameters:
- `method` (enum, required) -- HTTP method: "get", "post", "postJson", "delete", "put"
- `path` (string, required) -- API endpoint path (e.g., '/orgs/list/', '/workspace/{workspace_id}')
- `body` (object, optional) -- Request body (form-encoded for post/put, JSON for postJson)
- `params` (object, optional) -- Query parameters appended to the URL
- `timeout_ms` (number, optional) -- Timeout in ms (default 30000, max 60000)
#### Response Handling
The execute tool handles three response types automatically:
- **JSON** (most endpoints) -- parsed as standard Fast.io API envelope
- **Text** (markdown, plain text, etc.) -- returned as `{ content, content_type, http_status }`
- **Binary** (images, PDFs, etc.) -- returns metadata with guidance to use `download://` MCP resource
#### Reading Notes in Code Mode
Use `/readnote/` (returns JSON) instead of `/read/` (returns raw binary):
```
execute method="get" path="/workspace/{workspace_id}/storage/{node_id}/readnote/"
```
For reading uploaded files (non-notes), use the `download://` MCP resource:
```
resources/read uri="download://workspace/{workspace_id}/{node_id}"
```
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/REFERENCE.md
```markdown
# Fast.io for AI Agents
> **Version:** 1.26.0 | **Last updated:** 2026-03-06
>
> This guide is available at the `/current/agents/` endpoint on the connected API server.
**Workspaces for Agentic Teams. Collaborate, share, and query with AI — all through one API, free.**
Fast.io provides workspaces for agentic teams — where agents collaborate with other agents and with humans. Upload
outputs, create branded data rooms, ask questions about documents using built-in AI, and hand everything off to a human
when the job is done. No infrastructure to manage, no subscriptions to set up, no credit card required.
**MCP-enabled agents** should connect via the Model Context Protocol for the simplest integration — no raw HTTP calls
needed.
**Connection endpoints:**
- **Streamable HTTP (recommended):** `https://mcp.fast.io/mcp`
- **Legacy SSE:** `https://mcp.fast.io/sse`
The MCP server exposes **19 consolidated tools** using action-based routing — each tool covers a domain (e.g., `auth`,
`storage`, `upload`) and uses an `action` parameter to select the operation. See the "MCP Tool Architecture" section
below for the full tool list.
MCP-connected agents receive comprehensive workflow guidance through SERVER_INSTRUCTIONS at connection time, and can
read resources (`resources/read`) including `skill://guide` for full tool documentation, `session://status` for current
authentication state, and `download://` resource templates for direct file content retrieval.
This guide covers platform concepts and capabilities; the MCP server provides tool-level details through its standard
protocol interface. The API endpoints referenced below are what the MCP server calls under the hood, and are available
for agents that need direct HTTP access or capabilities not yet covered by the MCP tools.
---
## Why Agents Use Fast.io
### The Problem
Agentic teams — groups of agents working together and with humans — need a shared place to work. Today, agents cobble
together S3 buckets, presigned URLs, email attachments, and custom download pages. Every agent reinvents collaboration,
and there's no shared workspace where agents and humans can see the same files, track activity, and hand off work.
Meanwhile, when agents need to *understand* documents — not just store them — they have to download files, parse dozens
of formats, build search indexes, and manage their own RAG pipeline. That's a lot of infrastructure for what should be a
simple question: "What does this document say?"
### What Fast.io Solves
| Problem | Fast.io Solution |
|----------------------------------------------|---------------------------------------------------------------------------------------------------|
| No shared workspace for agentic teams | Workspaces where agents and humans collaborate with file preview, versioning, and AI |
| Agent-to-agent coordination lacks structure | Shared workspaces with activity feeds, comments, and real-time sync across team members |
| Sharing outputs with humans is awkward | Purpose-built shares (Send, Receive, Exchange) with link sharing, passwords, expiration |
| Collecting files from humans is harder | Receive shares let humans upload directly to your workspace — no email attachments |
| Understanding document contents | Built-in AI reads, summarizes, and answers questions about your documents and code |
| Building a RAG pipeline from scratch | Enable intelligence on a workspace and documents are automatically indexed, summarized, and queryable |
| Finding the right file in a large collection | Semantic search finds documents by meaning, not just filename |
| Handing a project off to a human | One-click ownership transfer — human gets the org, agent keeps admin access |
| Tracking what happened | Full audit trail with AI-powered activity summaries |
| Cost | Free. 50 GB storage, 5,000 monthly credits, no credit card |
---
## Getting Started — Choosing the Right Account Type
There are two ways to use Fast.io as an agent, depending on whether you're operating autonomously or assisting an
existing human user.
### Option 1: Autonomous Agent — Create an Agent Account
If you're operating as part of an agentic team (collaborating with other agents, sharing outputs with humans, running
workflows), create your own agent account:
1. `POST /current/user/` with `email_address`, `password`, `tos_agree=true`, `agent=true`
2. Authenticate with Basic Auth → get JWT
3. Verify your email address (required before using most endpoints):
- `POST /current/user/email/validate/` with `email` — sends a verification code to your email
- `POST /current/user/email/validate/` with `email` and `email_token` — validates the code and marks your account as verified
4. `POST /current/org/create/` with `domain` (required, 2-80 chars lowercase alphanumeric + hyphens) — an org is a collector of workspaces that can represent a company, team, business unit, or personal collection
5. `POST /current/org/{org_id}/create/workspace/` with `folder_name`, `name`, `perm_join`, `perm_member_manage` (all required — see Permission Values below)
Agent accounts get the free agent plan (50 GB, 5,000 monthly credits) and can transfer orgs to humans when ready. This
is the recommended path for autonomous agents.
#### Permission Values
Workspace and share creation require human-readable permission strings:
**Workspace `perm_join`** (who can auto-join from the org):
- `'Member or above'` (default) — any org member can join
- `'Admin or above'` — only org admins and owners
- `'Only Org Owners'` — only org owners
**Workspace `perm_member_manage`** (who can manage workspace members):
- `'Member or above'` (default) — any workspace member can manage
- `'Admin or above'` — only workspace admins and owners
**Share `access_options`** (who can access the share):
- `'Only members of the Share or Workspace'` (default)
- `'Members of the Share, Workspace or Org'`
- `'Anyone with a registered account'`
- `'Anyone with the link'` (allows password protection)
### Option 2: Assisting a Human — Use Their API Key
If a human already has a Fast.io account and wants your help managing their files, workspaces, or shares, they can
create an API key for you to use. No separate agent account is needed — you operate as the human user.
**How the human creates an API key:**
Go to **Settings → Devices & Agents → API Keys** and click **Create API Key**. Optionally enter a memo to label the
key (e.g., "CI pipeline" or "Agent access"), then click **Create**. Copy the key immediately — it is only displayed
once and cannot be retrieved later. Direct link: `https://go.fast.io/settings/api-keys`
Use the API key as a Bearer token: `Authorization: Bearer {api_key}`
The API key has the same permissions as the human user, so you can manage their workspaces, shares, and files directly.
### Option 3: Agent Account Invited to a Human's Org
If you want your own agent identity but need to work within a human's existing organization (their company, team, or personal collection), you can create an agent account and have the human invite you as a member. This gives you access to their workspaces and shares while keeping your own account separate.
**How the human invites the agent to their org:**
Go to **Settings → Your Organization → [Org Name] → Manage People** and click **Invite People**. Enter the agent's
email address, choose a permission level (Member or Admin), and click **Send Invites**. The agent account will receive
the invitation and can accept it via `POST /current/user/invitations/acceptall/`.
**How the human invites the agent to a workspace:**
Open the workspace, click the member avatars in the toolbar, then click **Manage Members**. Enter the agent's email
address, choose a permission level, and optionally check **Invite to org** to add them to the organization at the same
time. Click **Send Invites** — if the agent isn't already an org member and the toggle is off, they'll need an org
invite separately.
Alternatively, the human can invite the agent programmatically:
- **Org:** `POST /current/org/{org_id}/members/{agent_email}/` with `permission` level
- **Workspace:** `POST /current/workspace/{workspace_id}/members/{agent_email}/` with `permission` level
### Option 4: PKCE Browser Login — Secure Authentication Without Sharing Passwords
For the most secure authentication flow — especially when a human wants to authorize an agent without sharing their
password — use the PKCE (Proof Key for Code Exchange) browser login. No credentials pass through the agent at any point.
The `client_id` can be a pre-registered ID, a dynamically registered ID (via DCR), or an **HTTPS URL pointing to a
Client ID Metadata Document (CIMD)**. CIMD is the MCP specification's preferred registration method — the server
fetches client metadata from the URL on-the-fly, so no pre-registration is needed.
1. Agent calls `POST /current/oauth/authorize/` with PKCE parameters (`code_challenge`, `code_challenge_method=S256`,
`client_id`, `redirect_uri`, `response_type=code`) — gets back an authorization URL
2. The user opens the URL in their browser, signs in (supports SSO), and approves access
3. The browser displays an authorization code that the user copies back to the agent
4. Agent calls `POST /current/oauth/token/` with `grant_type=authorization_code`, the authorization `code`, and the
PKCE `code_verifier` — receives an access token and refresh token
5. The agent is now authenticated. Access tokens last **1 hour**, refresh tokens last **30 days**. Use
`POST /current/oauth/token/` with `grant_type=refresh_token` to get new access tokens without repeating the flow.
This is the recommended approach when:
- A human wants to grant agent access without sharing their password
- The organization uses SSO and password-based auth isn't available
- You need the strongest security guarantees (no credentials stored by the agent)
### Recommendations
| Scenario | Recommended Approach |
|----------|---------------------|
| Operating autonomously, storing files, building for users | Create an agent account with your own org (your personal collection of workspaces) |
| Helping a human manage their existing account | Ask the human to create an API key for you |
| Working within a human's org with your own identity | Create an agent account, have the human invite you |
| Building something to hand off to a human | Create an agent account, build it, then transfer the org |
| Human wants to authorize an agent without sharing credentials | Use PKCE browser login (Option 4) |
### Authentication & Token Lifecycle
All API requests require `Authorization: Bearer {token}` in the header. How you get that token depends on your access
pattern:
**JWT tokens (agent accounts):** Authenticate with `GET /current/user/auth/` using HTTP Basic Auth (email:password). The
response includes an `auth_token` (JWT). OAuth access tokens last **1 hour** and refresh tokens last **30 days**. When
your token expires, re-authenticate to get a new one. If the account has 2FA enabled, the initial token has limited
scope until 2FA verification is completed via `/current/user/auth/2factor/auth/{token}/`.
**API keys (human accounts):** API keys are long-lived and do not expire unless the human revokes them. No refresh flow
needed.
**Verify your token:** Call `GET /current/user/auth/check/` at any time to validate your current token and get the
authenticated user's ID. This is useful at startup to confirm your credentials are valid before beginning work, or to
detect an expired token without waiting for a 401 error on a real request.
### OAuth Scopes — Controlling Access
When using PKCE browser login, you can request scoped access tokens that limit what the agent can do. Scopes follow
an inheritance model — broader scopes automatically include access to their children.
**Scope types:**
| Scope Type | Description |
|------------------|-----------------------------------------------------------------------------|
| `all_orgs` | Access to all organizations the user owns or is a member of |
| `all_workspaces` | Access to all workspaces across accessible organizations |
| `all_shares` | Access to all shares across accessible organizations and workspaces |
**Inheritance:** `all_orgs` includes `all_workspaces`, which includes `all_shares`. Requesting `all_orgs` grants full
access to all orgs, workspaces, and shares the user has access to.
Pass the desired `scope_type` when initiating the PKCE authorization flow (`POST /current/oauth/authorize/`). If
omitted, the token defaults to full access (equivalent to `all_orgs`).
### Organizations — Collectors of Workspaces
An organization (org) is a collector of workspaces. It can represent a company, a business unit, a team, or simply your own personal collection. Every workspace and share lives under an org, and orgs are the billable entity — storage, credits, and member limits are tracked at the org level.
### Internal vs External Orgs
When working with Fast.io, an agent may interact with orgs in two different ways:
**Internal orgs** — orgs you created or were invited to join as a member. You have org-level access: you can see all
workspaces (subject to permissions), manage settings if you're an admin, and appear in the org's member list. Your own
orgs always show `member: true` in API responses.
**External orgs** — orgs you can access only through workspace membership. If a human invites you to their workspace
but does not invite you to their org, the org appears as external. You can see the org's name and basic public info, but
you cannot manage org settings, see other workspaces, or add members at the org level. External orgs show
`member: false` in API responses.
This distinction matters because an agent invited to a single workspace cannot assume it has access to the rest of that
org. It can only work within the workspaces it was explicitly invited to.
**Full org discovery requires both endpoints:**
- `GET /current/orgs/list/` — returns orgs you are a member of (`member: true`)
- `GET /current/orgs/list/external/` — returns orgs you access via workspace membership only (`member: false`)
**Always call both.** An agent that only calls `/orgs/list/` will miss every org where it was invited to a workspace but
not to the org itself — which is the most common pattern when a human adds an agent to help with a specific project. If
you skip `/orgs/list/external/`, you won't discover those workspaces at all.
**Example:** A human invites your agent to their "Q4 Reports" workspace. You can upload files, run AI queries, and
collaborate in that workspace. But you cannot create new workspaces in their org, view their billing, or access their
other workspaces. The org shows up in `/orgs/list/external/` — not `/orgs/list/`.
If the human later invites you to the org itself (via org member invitation), the org moves from external to internal and
you gain org-level access based on your permission level.
### Pagination
All list endpoints support offset-based pagination via query parameters. Use pagination to keep responses within token
limits and iterate through large collections.
**Query parameters:**
| Parameter | Type | Default | Max | Description |
|-----------|------|---------|-----|----------------------------|
| `limit` | int | 100 | 500 | Number of items to return |
| `offset` | int | 0 | — | Number of items to skip |
**Response metadata:** Every paginated response includes a `pagination` object:
```json
{
"pagination": {
"total": 42,
"limit": 100,
"offset": 0,
"has_more": false
}
}
```
**Paginating through results:**
```
# First page
GET /current/orgs/list/?limit=10&offset=0
# → pagination.has_more = true, pagination.total = 42
# Second page
GET /current/orgs/list/?limit=10&offset=10
# → pagination.has_more = true
# Continue until has_more = false
```
**Endpoints supporting pagination:**
| Endpoint | Collection Key |
|------------------------------------------------------|--------------------|
| `GET /current/orgs/all/` | `orgs` |
| `GET /current/orgs/list/` | `orgs` |
| `GET /current/orgs/list/external/` | `orgs` |
| `GET /current/shares/all/` | `shares` |
| `GET /current/workspace/{id}/members/list/` | `users` |
| `GET /current/org/{id}/billing/usage/members/list/` | `billable_members` |
| `GET /current/workspace/{id}/list/shares/` | `shares` |
| `GET /current/user/me/list/shares/` | `shares` |
| `GET /current/org/{id}/list/workspaces/` | `workspaces` |
| `GET /current/org/{id}/members/list/` | `users` |
| `GET /current/workspace/{id}/storage/search/` | `files` |
| `GET /current/share/{id}/storage/search/` | `files` |
| `GET /current/share/{id}/members/list/` | `users` |
---
## Core Capabilities
### 1. Workspaces — Shared Spaces for Agentic Teams
Workspaces are where agentic teams do their work. Each workspace has its own storage, member list, AI chat, and
activity feed — a shared environment where agents collaborate with other agents and with humans.
- **50 GB included storage** on the free agent plan
- **Files up to 1 GB** per upload
- **File versioning** — every edit creates a new version, old versions are recoverable
- **Folder hierarchy** — organize files however you want
- **Full-text and semantic search** — find files by name or content, and documents by meaning
- **Member roles** — Owner, Admin, Editor, Viewer with granular permissions
- **Real-time sync** — changes appear instantly for all members via WebSockets
#### Intelligence: On or Off
Workspaces have an **intelligence** toggle that controls whether AI features are active. This is a critical decision:
**Intelligence OFF** — the workspace stores files without AI indexing. You can still attach files directly to an AI chat
conversation (up to 20 files), but files are not persistently indexed. This is fine for coordination workflows where
you don't need to query your content.
**Intelligence ON** — the workspace becomes an AI-powered knowledge base. Every document and code file uploaded is automatically ingested,
summarized, and indexed for RAG. This enables:
- **RAG (retrieval-augmented generation)** — scope AI chat to entire folders or the full workspace and ask questions
across your indexed documents and code. The AI retrieves relevant passages and answers with citations.
- **Semantic search** — find files by meaning, not just keywords. "Show me contracts with indemnity clauses" works even
if those exact words don't appear in the filename.
- **Auto-summarization** — short and long summaries generated for every indexed document and code file, searchable and visible in the UI.
- **Metadata extraction** — AI pulls structured metadata from documents, code, and images automatically using templates.
Assign a template to a workspace, and every document uploaded is automatically extracted against that schema during
ingestion. You can also trigger extraction manually or in batch. See section 14 (Metadata) for the full API.
> **Coming soon:** RAG indexing support for images, video, and audio files. Currently only documents and code are indexed.
Intelligence is enabled by default when creating workspaces via the API for agent accounts. **Agents should explicitly
set intelligence to `false` unless the user needs RAG queries across many documents or AI-powered semantic search.**
The ingestion cost (10 credits/page) is significant and non-refundable — a 100-page document costs 1,000 credits to
ingest. If your team only needs a shared workspace for coordination, disable it to conserve credits.
**Agent use case:** Create a workspace per project or client. Enable intelligence only if agents or humans need to query the
content via RAG or semantic search. Upload reports, datasets, and deliverables. Invite other agents and human stakeholders.
Everything is organized, searchable, and versioned — and the whole team can see it.
> **Cost-saving tips:** Disable intelligence on storage-only workspaces to avoid ingestion costs. Use attach-only AI chat
> (no intelligence needed) for one-off file analysis — up to 20 files can be attached directly without indexing.
### 2. Shares — Structured Agent-Human Exchange
Shares are purpose-built spaces for exchanging files between your agentic team and external humans. Three modes cover
every exchange pattern:
| Mode | What It Does | Agent Use Case |
|--------------|-------------------------------|-----------------------------------------------|
| **Send** | Recipients can download files | Deliver reports, exports, generated content |
| **Receive** | Recipients can upload files | Collect documents, datasets, user submissions |
| **Exchange** | Both upload and download | Collaborative workflows, review cycles |
#### Share Features
- **Password protection** — require a password for link access
- **Expiration dates** — shares auto-expire after a set period
- **Download controls** — enable or disable file downloads
- **Access levels** — `'Only members of the Share or Workspace'`, `'Members of the Share, Workspace or Org'`, `'Anyone with a registered account'`, or `'Anyone with the link'`
- **Custom branding** — background images, gradient colors, accent colors, logos
- **Post-download messaging** — show custom messages and links after download
- **Up to 3 custom links** per share for context or calls-to-action
- **Guest chat** — let share recipients ask questions in real-time
- **AI-powered auto-titling** — shares automatically generate smart titles from their contents
- **Activity notifications** — get notified when files are sent or received
- **Comment controls** — configure who can see and post comments (owners, guests, or both)
#### Two Storage Modes
When creating a share, you choose a `storage_mode` that determines how the share's files are managed:
- **`room`** (independent storage, default) — the share has its own isolated storage. Files are added directly to the
share and are independent of any workspace. This creates a self-contained data room — changes to workspace files don't
affect the room, and vice versa. Perfect for final deliverables, compliance packages, archived reports, or any
scenario where you want an immutable snapshot.
- **`shared_folder`** (workspace-backed) — the share is backed by a specific folder in a workspace. The share displays
the live contents of that folder — any files added, updated, or removed in the workspace folder are immediately
reflected in the share. No file duplication, so no extra storage cost. To create a shared folder, pass
`storage_mode=shared_folder` and `folder_node_id={folder_opaque_id}` when creating the share. Note: expiration dates
are not allowed on shared folder shares since the content is live.
Both modes look the same to share recipients — a branded data room with file preview, download controls, and all share
features. The difference is whether the content is a snapshot (room) or a live view (shared folder).
**Agent use case:** Generate a quarterly report, create a Send share with your client's branding, set a 30-day
expiration, and share the link. The client sees a branded page with instant file preview — not a raw download link.
### 3. QuickShare — Instant File Handoff
Need to toss a file to someone right now? QuickShare creates a share from a single file with zero configuration.
Automatic 30-day expiration. No setup, no decisions.
**Agent use case:** Debug log, sample output, or quick artifact? QuickShare it and send the link. Done.
### 4. Built-In AI — Ask Questions About Your Files
Fast.io's AI is a **read-only tool** — it can read and analyze file contents, but it cannot modify files, change
workspace settings, manage members, or read events. It answers questions about your documents, nothing more. For any
action beyond reading file content, your agent must use the API or MCP server directly.
Fast.io's AI lets agents query documents through two chat types, with or without persistent indexing. Both types
augment file knowledge with information from the web when relevant.
#### Chat Types
**`chat`** — Basic AI conversation. Does not use file context from the workspace index. Use this for general questions
or when you don't need to reference stored files.
**`chat_with_files`** — AI conversation grounded in your files. This is the type you use when you want the AI to read,
analyze, and cite your documents. Requires the workspace to have **intelligence enabled** if using folder/file scope
(RAG). Supports two mutually exclusive modes for providing file context:
1. **Folder/file scope** (RAG) — limits the search space for retrieval. The AI searches the indexed content of files
within the specified scope, retrieves relevant passages, and answers with citations. Requires intelligence enabled
and files in `ready` AI state.
2. **File attachments** — files are directly attached to the conversation. The AI reads the full content of the attached
files. Does not require intelligence — any file with a ready preview can be attached. Max 20 files, 200MB total.
These two modes cannot be combined in a single chat — use scope OR attachments, not both.
**Auto-promotion:** If you create a chat with `type=chat` but include `files_scope`, `folders_scope`, or `files_attach`,
the system automatically promotes the type to `chat_with_files`. You don't need to worry about setting the type exactly
right — the intent is unambiguous when file parameters are present.
#### Intelligence Setting — When to Enable It
The `intelligence` toggle on a workspace controls whether uploaded documents and code files are automatically ingested, summarized, and
indexed for RAG. **For most workflows, intelligence should be OFF.** Ingestion costs 10 credits/page and is non-refundable — a 100-page
document costs 1,000 credits. This can be the largest credit consumer for agent accounts.
**Enable intelligence only when:**
- You have many files and need RAG queries across them to answer questions
- You want scoped RAG queries against folders or the entire workspace
- You need AI-powered semantic search across large document sets
- You're building a persistent knowledge base that will be queried repeatedly
**Disable intelligence (recommended default) when:**
- You're using the workspace for file storage, sharing, or team coordination
- You only need to analyze specific files (use file attachments instead — no intelligence needed)
- You're uploading deliverables, reports, or outputs that don't need to be queried
- You want to conserve credits — disabling avoids all ingestion costs
Even with intelligence disabled, you can still use `chat_with_files` with **file attachments** — any file that has a
ready preview can be attached directly to a chat for one-off analysis.
#### AI State — File Readiness for RAG
Every document and code file in an intelligent workspace has an `ai_state` field that tracks its ingestion progress:
| State | Meaning |
|---------------|---------------------------------------------------|
| `disabled` | AI processing disabled for this file |
| `pending` | Queued for processing |
| `in_progress` | Currently being ingested and indexed |
| `ready` | Processing complete — file is available for RAG |
| `failed` | Processing failed |
**Only documents and code files with `ai_state: ready` are included in folder/file scope searches.** If you upload files and immediately
create a scoped chat, recently uploaded files may not yet be indexed. Use the activity polling endpoint to wait for
`ai_state` changes before querying.
#### Folder Scope vs File Attachments
| Feature | Folder/File Scope (RAG) | File Attachments |
|----------------------|--------------------------------------------|------------------------------------------|
| How it works | Limits RAG search space | Files read directly by AI |
| Requires intelligence| Yes | No |
| Requires `ai_state` | Files must be `ready` | Files must have a ready preview |
| Best for | Many files, knowledge retrieval | Specific files, direct analysis |
| Max references | 100 folder refs (subfolder tree expansion) | 20 files, 200MB total |
| Default behavior | No scope = entire workspace | N/A |
**Folder scope parameters:**
- `folders_scope` — comma-separated `nodeId:depth` pairs (depth 1-10, max 100 subfolder refs). The depth controls how
many levels of subfolders are expanded — only subfolder references count toward the 100 limit, not individual files
within those folders. The RAG backend automatically searches all indexed documents inside the scoped folders.
- `files_scope` — comma-separated `nodeId:versionId` pairs (max 100 refs). nodeId is required; versionId is required
in the pair format but will be **auto-resolved to the node's current version** if left empty (e.g., `nodeId:` with
nothing after the colon). Get the versionId from the file's `version` field in storage list/details responses.
Limits RAG retrieval to specific file versions.
- **Default scope is the entire workspace** — if you omit both `files_scope` and `folders_scope`, the AI searches
all indexed documents. This is the recommended approach when you want to query across everything. Only provide scope
parameters when you need to narrow the search to specific files or folders.
**Important — how folder scope works internally:**
Folder scope defines a search boundary, not a file list. When you pass `folders_scope`, the system expands the specified
folders into a set of subfolder references up to the given depth. The RAG backend then searches all indexed documents within
those folders automatically. You do **not** need to enumerate or list individual files — just provide the top-level
folder ID and the desired depth. A folder containing thousands of files with only a few subfolders will work fine,
because only the subfolder references (not file references) count toward the 100 limit. If you need to query the
entire workspace, omit `folders_scope` entirely — the default scope is already the full workspace.
**File attachment parameter:**
- `files_attach` — comma-separated `nodeId:versionId` pairs (max 20 files, 200MB total). nodeId is required;
versionId will be **auto-resolved to the current version** if left empty. **Only file nodes are accepted — passing
a folder nodeId will be rejected.** Files are read directly, not searched via RAG. To include folder contents, use
`folders_scope` instead.
#### Notes as Knowledge Grounding
Notes are markdown documents created directly in workspace storage via the API
(`POST /current/workspace/{id}/storage/{folder}/createnote/`). In an intelligent workspace, notes are ingested and
indexed just like uploaded files. This makes notes a way to store long-term knowledge that becomes grounding material
for future AI queries.
**Agent use case:** Store project context, decision logs, or reference material as notes. When you later ask the AI
"What was the rationale for choosing vendor X?", the note containing that decision is retrieved and cited — even months
later.
Notes within a folder scope are included in RAG queries when intelligence is enabled.
#### How to Write Effective Questions
The way you phrase questions depends on whether you're using folder scope (RAG) or file attachments.
**With folder/file scope (RAG):**
Write questions that are likely to match content in your indexed files. The AI searches the scope for relevant passages,
retrieves them, and uses them as citations to answer your question. Think of it as a search query that returns context
for an answer.
- Good: "What are the payment terms in the vendor contracts?" — matches specific content in files
- Good: "Summarize the key findings from the Q3 analysis reports" — retrieves relevant sections
- Good: "What risks were identified in the security audit?" — finds specific content to cite
- Bad: "Tell me about these files" — too vague for retrieval, no specific content to match
- Bad: "What's in this workspace?" — the AI can't meaningfully search for "everything"
If no folder scope is specified, the search defaults to all indexed documents in the workspace. For large workspaces, narrowing the
scope to specific folders improves relevance and reduces token usage.
**With file attachments:**
You can be more direct and simplistic since the AI reads the full file content. No retrieval step — the AI has the
complete file in context.
- "Describe this image in detail"
- "Extract all dates and amounts from this invoice"
- "Convert this CSV data into a summary table"
- "What programming language is this code written in and what does it do?"
**Personality:** The `personality` parameter controls the tone and length of AI responses. Pass it when creating a chat
or sending a message:
- `concise` — short, direct answers with minimal explanation
- `detailed` — comprehensive answers with context and evidence (default)
This makes a significant difference in response quality for your use case. Agents that need to extract data or get quick
answers should use `concise` to avoid wasting tokens on lengthy explanations. Use `detailed` when you need thorough
analysis with supporting evidence.
You can also control verbosity in the question itself — for example, "In one sentence, summarize this report" or "List
only the file names, no explanations." Combining `concise` personality with direct questions produces the shortest
responses.
#### Waiting for AI Responses
After sending a message, the AI processes it asynchronously. You need to wait for the response to be ready.
**Message states:**
| State | Meaning |
|-------------------|--------------------------------------|
| `ready` | Queued for processing |
| `in_progress` | AI is generating the response |
| `complete` | Response finished |
| `errored` | Processing failed |
| `post_processing` | Finalizing (citations, formatting) |
**Option 1: SSE streaming (recommended for real-time display)**
`GET /current/workspace/{id}/ai/chat/{chat_id}/message/{message_id}/read/`
Returns a `text/event-stream` with response chunks as they're generated. The stream ends with a `done` event when the
response is complete. Response chunks include the AI's text, citations pointing to specific files/pages/snippets, and
any structured data (tables, analysis).
**Option 2: Activity polling (recommended for background processing)**
Don't poll the message endpoint in a loop. Instead, use the activity long-poll:
`GET /current/activity/poll/{workspace_id}?wait=95&lastactivity={timestamp}`
When `ai_chat:{chatId}` appears in the activity response, the chat has been updated — fetch the message details to get
the completed response. This is the most efficient approach when you don't need to stream the response in real-time.
**Option 3: Fetch completed response**
`GET /current/workspace/{id}/ai/chat/{chat_id}/message/{message_id}/details/`
Check the `state` field. If `complete`, the `response.text` contains the full answer and `response.citations` contains
the file references.
#### Linking Users to AI Chats
To send a user directly to an AI chat in the workspace UI, append a `chat` query parameter to the workspace storage
URL:
`https://{org.domain}.fast.io/workspace/{workspace.folder_name}/storage/root?chat={chat_opaque_id}`
This opens the workspace with the specified chat visible in the AI panel.
#### Supported Content Types
**Indexed for RAG** (requires Intelligence ON):
- Documents (PDF, Word, text, markdown)
- Code files (all common languages)
**File attachments only** (no RAG indexing):
- Spreadsheets (Excel, CSV)
- Images (all common formats) — *RAG indexing coming soon*
- Video (all common formats) — *RAG indexing coming soon*
- Audio (all common formats) — *RAG indexing coming soon*
#### AI Share — Export to External AI Tools
Generate temporary download URLs for your files, formatted as markdown, for pasting into external AI assistants like
ChatGPT or Claude. Up to 25 files, 50MB per file, 100MB total. Links expire after 5 minutes. This is separate from the
built-in AI chat — use it when you want to analyze files with a different model or tool.
**Agent use case:** A user asks "What were Q3 margins?" You have 50 financial documents in an intelligent workspace.
Instead of downloading and parsing all 50, create a `chat_with_files` scoped to the finance folder and ask. The AI
searches the indexed content, retrieves relevant passages, and answers with citations. Pass the cited answer — with
source references — back to the user.
#### Semantic Search — Fast Retrieval Without LLM
Semantic search lets you find relevant document chunks by meaning without creating a chat or waiting for an LLM response.
It returns ranked text snippets with relevance scores — no LLM round-trip, no token cost beyond the search itself.
**When to use search vs chat:**
| | Semantic Search | AI Chat |
|---|---|---|
| **What it does** | Returns raw document chunks ranked by relevance | Creates an LLM-generated answer with citations |
| **Speed** | Fast — vector lookup only | Slower — retrieval + LLM generation |
| **Cost** | Low — no LLM token cost | Higher — LLM tokens consumed per message |
| **Best for** | Retrieval, lookup, finding specific content | Synthesis, analysis, summarizing across documents |
| **Returns** | Text snippets + scores + file references | Natural language answer + citations |
**Endpoints:**
```
GET /current/workspace/{workspace_id}/ai/search/
GET /current/share/{share_id}/ai/search/
```
**Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `query_text` | string | Yes | — | Search query, 2–1,000 characters |
| `files_scope` | string | No | All indexed files | Comma-separated `nodeId:versionId` pairs (max 100) |
| `folders_scope` | string | No | All indexed files | Comma-separated `nodeId:depth` pairs (max 100, depth 1–10) |
| `limit` | integer | No | 100 | Results per page, 1–500 |
| `offset` | integer | No | 0 | Pagination offset |
Requires `intelligence=true` on the workspace or share. Only files with `ai_state: ready` are included.
**Response example:**
```json
{
"result": true,
"results": [
{
"content": "The quarterly revenue showed a 15% increase...",
"score": 0.95,
"node": {
"id": "f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4",
"type": "file",
"name": "quarterly-report.pdf",
"mimetype": "application/pdf",
"ai": { "state": "ready", "attach": true, "summary": true }
}
}
],
"pagination": { "total": 25, "limit": 100, "offset": 0, "has_more": false }
}
```
Each result contains:
- `content` — the matched text snippet from the indexed document
- `score` — relevance score (0.0–1.0, higher is more relevant)
- `node` — full file resource (or `null` if the file was deleted)
**Agent memory pattern:** Upload context documents (meeting notes, research, reference material) to an intelligent
workspace. Later, use `ai/search` to retrieve relevant chunks without burning LLM credits. This is significantly
cheaper than creating a chat for every lookup and is ideal for agents that need to recall information across sessions —
treat the intelligent workspace as a persistent memory store and search as the retrieval mechanism.
**Agent use case — multi-step research:** An agent researching a topic uploads 200 papers to a workspace with
intelligence enabled. For each research question, it calls `ai/search` to find the most relevant passages, reads the
top results, and only escalates to AI chat when it needs the LLM to synthesize across multiple sources. This approach
uses a fraction of the credits compared to chatting for every question.
### 5. File Preview — No Download Required
Files uploaded to Fast.io get automatic preview generation. When humans open a share or workspace, they see the content
immediately — no "download and open in another app" friction.
**Supported preview formats:**
- **Images** — full-resolution with auto-rotation and zoom
- **Video** — HLS adaptive streaming (50-60% faster load than raw video)
- **Audio** — interactive waveform visualization
- **PDF** — page navigation, zoom, text selection
- **Spreadsheets** — grid navigation with multi-sheet support
- **Code & text** — syntax highlighting, markdown rendering
**Agent use case:** Your generated PDF report doesn't just appear as a download link. The human sees it rendered inline,
can flip through pages, zoom in, and comment on specific sections — all without leaving the browser.
### 6. Notes — Markdown Documents as Knowledge
Notes are a storage node type (alongside files and folders) that store markdown content directly on the server. They
live in the same folder hierarchy as files, are versioned like any other node, and appear in storage listings with
`type: "note"`.
#### Creating and Updating Notes
**Create:** `POST /current/workspace/{id}/storage/{parent_id}/createnote/`
- `name` (required) — filename, must end in `.md`, max 100 characters (e.g., `"project-context.md"`)
- `content` (required) — markdown text, max 100 KB. Must be valid UTF-8 (UTF8MB4). Control characters (`\p{C}` except `\t`, `\n`, `\r`) are stripped.
**Update:** `POST /current/workspace/{id}/storage/{node_id}/updatenote/`
- `name` (optional) — rename the note (must end in `.md`)
- `content` (optional) — replace the markdown content (max 100 KB). Must be valid UTF-8 (UTF8MB4). Control characters (`\p{C}` except `\t`, `\n`, `\r`) are stripped.
- At least one of `name` or `content` must be provided
Notes can also be moved, copied, deleted, and restored using the same storage endpoints as files and folders.
#### Notes as Long-Term Knowledge Grounding
In an intelligent workspace, notes are automatically ingested and indexed just like uploaded documents. This makes notes a
powerful way to **bank knowledge over time** — any facts, context, or decisions stored in notes become grounding
material for future AI queries.
When an AI chat uses folder scope (or defaults to the entire workspace), notes within that scope are searched alongside
files. The AI retrieves relevant passages from notes and cites them in its answers.
**Use cases:**
- Store project context, decisions, and rationale as notes. Months later, ask "Why did we choose vendor X?" and the AI
retrieves the note with that decision.
- After researching a topic, save key findings in a note. Future AI chats automatically use those findings as grounding.
- Create reference documents (style guides, naming conventions, process docs) that inform all future AI queries in the
workspace.
#### Linking Users to Notes
**Open a note in the workspace UI** — append `?note={opaque_id}` to the workspace storage URL:
`https://{org.domain}.fast.io/workspace/{folder_name}/storage/root?note={note_opaque_id}`
**Link directly to the note preview** — use the standard file preview URL:
`https://{org.domain}.fast.io/workspace/{folder_name}/preview/{note_opaque_id}`
The preview link is more effective if you want the user to focus on reading just that note, while the `?note=` link
opens the note within the full workspace context.
### 7. Comments & Annotations
Humans can leave feedback directly on files, anchored to specific content:
- **Image comments** — anchored to regions of the image
- **Video comments** — anchored to timestamps with frame-stepping and spatial region selection
- **Audio comments** — anchored to timestamps or time ranges
- **PDF comments** — anchored to specific pages with optional text selection
- **Threaded replies** — single-level threads under each comment (replies to replies are auto-flattened)
- **Emoji reactions** — one reaction per user per comment, new replaces previous
- **Mentions** — tag users with `@[user:USER_ID:Display Name]` syntax in the comment body
**Character limits:** The comment `body` field has a hard maximum of **8,192 characters** — this includes the full mention tag markup. When you convert a short `@name` reference into the bracket syntax (e.g., `@[user:abc123:Jane Smith]`), the expanded string is what counts toward the limit. The display text (everything except mention markup) is separately capped at **500 characters**. Build your comment body with the expanded tags first, then verify the total length before submitting.
**Linking users to comments:** Link users to the file preview URL. The comments sidebar opens automatically in workspace
previews, and in share previews when comments are enabled on the share.
Base preview URL:
`https://{org.domain}.fast.io/workspace/{folder_name}/preview/{file_opaque_id}`
For shares: `https://go.fast.io/shared/{custom_name}/{title-slug}/preview/{file_opaque_id}`
**Deep linking to a specific comment:** Append `?comment={comment_id}` to the preview URL. The UI scrolls to and
highlights the comment automatically:
`https://{org.domain}.fast.io/workspace/{folder_name}/preview/{file_opaque_id}?comment={comment_id}`
**Deep linking to media/document positions:** For comments anchored to specific locations, combine with position
parameters:
- `?t={seconds}` — seeks to a timestamp in audio/video (e.g., `?comment={id}&t=45.5`)
- `?p={pageNum}` — navigates to a page in PDFs (e.g., `?comment={id}&p=3`)
**Agent use case:** You generate a design mockup. The human comments "Change the header color" on a specific region of
the image. You read the comment, see exactly what region they're referring to, and regenerate.
### 8. File Uploads — Getting Files Into Fast.io
Agents upload files through a session-based API. There are two paths depending on file size:
#### Small Files (Under 4 MB)
For files under 4 MB, upload in a single request. Send the file as `multipart/form-data` with the `chunk` field
containing the file data, plus `org` (your org domain), `name`, `size`, and `action=create`.
To have the file automatically added to a workspace or share, include `instance_id` (the workspace or share ID) and
optionally `folder_id` (the target folder's OpaqueId, or omit for root). The response includes `new_file_id` — the
permanent OpaqueId of the file in storage. No further steps needed.
```
POST /current/upload/
Content-Type: multipart/form-data
Fields: org, name, size, action=create, instance_id, folder_id, chunk (file)
→ Response: { "result": true, "id": "session-id", "new_file_id": "2abc..." }
```
#### Large Files (4 MB and Above)
Large files use chunked uploads. The flow has five steps:
1. **Create a session** — `POST /current/upload/` with `org`, `name`, `size`, `action=create`, `instance_id`, and
optionally `folder_id`. Returns a session `id`.
2. **Upload chunks** — Split the file into **5 MB chunks** (last chunk may be smaller). For each chunk, send
`POST /current/upload/{session_id}/chunk/` as `multipart/form-data` with the `chunk` field (binary data), `order`
(1-based — first chunk is `order=1`), and `size`. You can upload up to **3 chunks in parallel** per session.
3. **Trigger assembly** — Once all chunks are uploaded, call `POST /current/upload/{session_id}/complete/`. The server
verifies chunks and combines them into a single file.
4. **Poll for completion** — The upload progresses through states asynchronously. Poll the session details with the
built-in long-poll:
`GET /current/upload/{session_id}/details/?wait=60`
The server holds the connection for up to 60 seconds and returns immediately when the status changes:
| Status | Meaning | What to Do |
|--------|---------|------------|
| `ready` | Awaiting chunks | Upload chunks |
| `uploading` | Receiving chunks | Continue uploading |
| `assembling` | Combining chunks | Keep polling |
| `complete` | Assembled, awaiting storage | Keep polling |
| `storing` | Being added to storage | Keep polling |
| **`stored`** | **Done** — file is in storage | Read `new_file_id`, clean up |
| `assembly_failed` | Assembly error (terminal) | Check `status_message` |
| `store_failed` | Storage import failed (terminal) | Check `status_message`, handle error |
Stop polling when status is `stored`, `assembly_failed`, or `store_failed`.
5. **Clean up** — Delete the session after completion: `DELETE /current/upload/{session_id}/`.
#### Optional Integrity Hashing
Include `hash` (SHA-256 hex digest) and `hash_algo=sha256` on each chunk for server-side integrity verification. You can
also provide a full-file hash in the session creation request instead.
#### Resuming Interrupted Uploads
If a connection drops mid-upload, the session persists on the server. To resume:
1. Fetch the session: `GET /current/upload/{session_id}/details/`
2. Read the `chunks` map — keys are chunk numbers already uploaded, values are byte sizes
3. Upload only the missing chunks
4. Trigger assembly and continue as normal
#### Manual Storage Placement
If you omit `instance_id` when creating the session, the file is uploaded but not placed in any workspace or share. You
can add it to storage manually afterward:
```
POST /current/workspace/{id}/storage/{folder}/addfile/
Body: from={"type":"upload","upload":{"id":"{session_id}"}}
```
This is useful when you need to upload first and decide where to place the file later.
#### MCP Binary Upload — Three Approaches
MCP agents have three ways to pass binary data when uploading chunks. Each uses the `upload` tool's `chunk` action
with exactly one of `data`, `blob_ref`, or `content` (for text):
**1. `data` parameter (base64) — simplest for MCP agents**
Pass base64-encoded binary directly in the `data` parameter of the `chunk` action. No extra steps required. Works
with any MCP client. Adds ~33% size overhead from base64 encoding.
**2. `stage-blob` action — MCP tool-based blob staging**
Use the `upload` tool's `stage-blob` action with `data` (base64) to pre-stage binary data as a blob. Returns a
`blob_id` that you pass as `blob_ref` in the `chunk` call. Useful when decoupling staging from uploading or preparing
multiple chunks in advance.
1. `upload` action `stage-blob` with `data` (base64-encoded binary) → returns `{ blob_id, size }`
2. `upload` action `chunk` with `blob_ref` set to the `blob_id`
**3. `POST /blob` endpoint — HTTP blob staging for non-MCP clients**
A sidecar HTTP endpoint that accepts raw binary data outside the JSON-RPC pipe, avoiding base64 encoding entirely.
Useful for clients that can make direct HTTP requests alongside MCP tool calls.
1. `POST /blob` with `Mcp-Session-Id` header and raw bytes as the request body → returns `{ blob_id, size }`
2. `upload` action `chunk` with `blob_ref` set to the `blob_id`
**Blob constraints (apply to both staging methods):**
- Blobs expire after **5 minutes** — stage and consume them promptly
- Each blob is consumed (deleted) on first use and cannot be reused
- Maximum blob size: **100 MB**
**Agent use case:** You're generating a 200 MB report. Create an upload session targeting the client's workspace, split
the file into 5 MB chunks, upload 3 at a time, trigger assembly, and poll until `stored`. The file appears in the
workspace with previews generated automatically. Use the activity polling endpoint (section 13) to know when AI indexing
completes if intelligence is enabled.
### 9. URL Import — Pull Files From Anywhere
When you need to add a file from the web, use `POST /current/web_upload/` with `source_url` instead of downloading it
locally and re-uploading. This is faster because the file transfers server-to-server — your agent never touches the
bytes.
- Supports any HTTP/HTTPS URL
- Supports OAuth-protected sources: **Google Drive, OneDrive, Dropbox**
- Files go through the same processing pipeline (preview generation, AI indexing if intelligence is enabled, virus
scanning)
**Check progress after submitting.** Web uploads are processed asynchronously by Fast.io's server-side fetch agent,
which may be blocked or rate-limited by the source. The import can fail silently if the source rejects the request, times
out, or returns an error. Monitor the upload status to confirm the file was actually retrieved and stored before
reporting success to the user.
**Security note:** The `web_upload` endpoint instructs the Fast.io cloud server to fetch the URL — not the agent's
local environment. The Fast.io server is a public cloud service with no access to the agent's local network, internal
systems, or private infrastructure. It can only reach publicly accessible URLs and supported OAuth-authenticated cloud
storage providers. No internal or private data is exposed beyond what the agent could already access through its own
network requests.
**Agent use case:** A user says "Add this Google Doc to the project." You call `POST /current/web_upload/` with the URL.
Fast.io downloads it server-side, generates previews, indexes it for AI, and it appears in the workspace. No local I/O —
and no bandwidth consumed by your agent.
### 10. Real-Time Collaboration
Fast.io uses WebSockets for instant updates across all connected clients:
- **Live presence** — see who's currently viewing a workspace or share
- **Cursor tracking** — see where other users are navigating
- **Follow mode** — click a user to mirror their exact navigation
- **Instant file sync** — uploads, edits, and deletions appear immediately for all viewers
### 11. Ownership Transfer — Hand Off to Humans
The killer feature for agents: build something, then give it to a human. This is also the upgrade path when the agent
plan's 5,000 monthly credits are exhausted or plan limits are reached — transferring to a human is the only way to
upgrade beyond the agent plan.
**Important:** Only `agent` account types can create transfer tokens. This is why agents should **always** create
accounts with `agent=true`. If you created a human account, you cannot use the transfer/claim API — you must direct the
user to upgrade the org themselves.
1. Agent creates an org, sets up workspaces, uploads files, configures shares
2. Agent generates a transfer token via `POST /current/org/{org_id}/transfer/token/create/` (64-char string, valid 72
hours, max 5 active tokens per org)
3. Agent sends the claim URL to the human: `https://go.fast.io/claim?token={token}`
4. Human clicks the link, logs in (or creates an account), and claims the org
**What happens:**
- Human becomes the owner of the org and all workspaces
- Agent is demoted to admin (can still manage files and shares)
- Human gets the free plan (credit-based, no trial period)
- Human can upgrade to Pro or Business at any time for unlimited credits and expanded limits
**Agent use case:** A user says "Set up a project workspace for my team." You create the org, build out workspace
structure, upload templates, configure shares for client deliverables, invite agents and human team members — then
transfer ownership. The human walks into a fully configured platform with an agentic team already in place. You stay on
as admin to keep managing things.
**Credit exhaustion use case:** Your agent hits the 5,000 credit limit mid-month. Create a transfer token, send the
claim URL to the human user, and let them know they can upgrade to Pro or Business for unlimited credits. After
claiming, the human upgrades and the org is no longer credit-limited.
### 12. Events — Real-Time Audit Trail
Events give agents a real-time audit trail of everything that happens across an organization. Instead of scanning entire
workspaces to detect what changed, query the events feed to see exactly which files were uploaded, modified, renamed, or
deleted — and by whom, and when. This makes it practical to build workflows that react to changes: processing a document
the moment it arrives, flagging unexpected permission changes, or generating a daily summary of activity for a human.
The activity log is also the most efficient way for an agent to stay in sync with a workspace over time. Rather than
periodically listing every file and comparing against a previous snapshot, check events since your last poll to get a
precise diff. This is especially valuable in large workspaces where full directory listings are expensive.
#### What Events Cover
- **File operations** — uploads, downloads, moves, renames, deletes, version changes
- **Membership changes** — new members added, roles changed, members removed
- **Share activity** — share created, accessed, files downloaded by recipients
- **Settings updates** — workspace or org configuration changes
- **Billing events** — credit usage, plan changes
- **AI operations** — ingestion started, indexing complete, chat activity
#### Querying Events
Search and filter events with `GET /current/events/search/`:
- **Scope by profile** — filter by `workspace_id`, `share_id`, `org_id`, or `user_id`
- **Filter by type** — narrow to specific event names, categories, or subcategories (see reference below)
- **Date range** — use `created-min` and `created-max` for time-bounded queries
- **Pagination** — offset-based with `limit` (1-250) and `offset`
Get full details for a single event with `GET /current/event/{event_id}/details/`, or mark it as read with
`GET /current/event/{event_id}/ack/`.
#### Event Categories
Use the `category` parameter to filter by broad area:
| Category | What It Covers |
|---------------|-------------------------------------------------------|
| `user` | Account creation, updates, deletion, avatar changes |
| `org` | Organization lifecycle, settings, transfers |
| `workspace` | Workspace creation, updates, archival, file operations |
| `share` | Share lifecycle, settings, file operations |
| `node` | File and folder operations (cross-profile) |
| `ai` | AI chat, summaries, RAG indexing |
| `invitation` | Member invitations sent, accepted, declined |
| `billing` | Subscriptions, trials, credit usage |
| `domain` | Custom domain configuration |
| `apps` | Application integrations |
| `metadata` | Metadata extraction, templates, key-value updates |
#### Event Subcategories
Use the `subcategory` parameter for finer filtering within a category:
| Subcategory | What It Covers |
|------------------|------------------------------------------------------|
| `storage` | File/folder add, move, copy, delete, restore, download |
| `comments` | Comment created, updated, deleted, mentioned, replied, reaction |
| `members` | Member added/removed from org, workspace, or share |
| `lifecycle` | Profile created, updated, deleted, archived |
| `settings` | Configuration and preference changes |
| `security` | Security-related events (2FA, password) |
| `authentication` | Login, SSO, session events |
| `ai` | AI processing, chat, indexing |
| `invitations` | Invitation management |
| `billing` | Subscription and payment events |
| `assets` | Avatar/asset updates |
| `upload` | Upload session management |
| `transfer` | Cross-profile file transfers |
| `import_export` | Data import/export operations |
| `quickshare` | Quick share operations |
| `metadata` | Metadata operations |
#### Common Event Names
Use the `event` parameter to filter by exact event name. Here are the most useful ones for agents:
**File operations (workspace):**
`workspace_storage_file_added`, `workspace_storage_file_deleted`, `workspace_storage_file_moved`,
`workspace_storage_file_copied`, `workspace_storage_file_updated`, `workspace_storage_file_restored`,
`workspace_storage_folder_created`, `workspace_storage_folder_deleted`, `workspace_storage_folder_moved`,
`workspace_storage_download_token_created`, `workspace_storage_zip_downloaded`,
`workspace_storage_file_version_restored`, `workspace_storage_link_added`
**File operations (share):**
`share_storage_file_added`, `share_storage_file_deleted`, `share_storage_file_moved`,
`share_storage_file_copied`, `share_storage_file_updated`, `share_storage_file_restored`,
`share_storage_folder_created`, `share_storage_folder_deleted`, `share_storage_folder_moved`,
`share_storage_download_token_created`, `share_storage_zip_downloaded`
**Comments:**
`comment_created`, `comment_updated`, `comment_deleted`, `comment_mentioned`, `comment_replied`,
`comment_reaction`
**Membership:**
`added_member_to_org`, `added_member_to_workspace`, `added_member_to_share`,
`removed_member_from_org`, `removed_member_from_workspace`, `removed_member_from_share`,
`membership_updated`
**Workspace lifecycle:**
`workspace_created`, `workspace_updated`, `workspace_deleted`, `workspace_archived`, `workspace_unarchived`
**Share lifecycle:**
`share_created`, `share_updated`, `share_deleted`, `share_archived`, `share_unarchived`,
`share_imported_to_workspace`
**AI:**
`ai_chat_created`, `ai_chat_new_message`, `ai_chat_updated`, `ai_chat_deleted`, `ai_chat_published`,
`node_ai_summary_created`, `workspace_ai_share_created`
**Metadata:**
`metadata_kv_update`, `metadata_kv_delete`, `metadata_kv_extract`,
`metadata_template_update`, `metadata_template_delete`,
`metadata_view_update`, `metadata_view_delete`, `metadata_template_select`
**Quick shares:**
`workspace_quickshare_created`, `workspace_quickshare_updated`, `workspace_quickshare_deleted`,
`workspace_quickshare_file_downloaded`, `workspace_quickshare_file_previewed`
**Invitations:**
`invitation_email_sent`, `invitation_accepted`, `invitation_declined`
**User:**
`user_created`, `user_updated`, `user_deleted`, `user_email_reset`, `user_asset_updated`
**Org:**
`org_created`, `org_updated`, `org_closed`, `org_transfer_token_created`, `org_transfer_completed`
**Billing:**
`subscription_created`, `subscription_cancelled`, `billing_free_trial_ended`
#### Example Queries
**Recent comments in a workspace:**
```
GET /current/events/search/?workspace_id={id}&subcategory=comments&limit=50
```
**Files uploaded to a share in the last 24 hours:**
```
GET /current/events/search/?share_id={id}&event=share_storage_file_added&created-min=2025-01-19T00:00:00Z
```
**All membership changes across an org:**
```
GET /current/events/search/?org_id={id}&subcategory=members
```
**AI activity in a workspace:**
```
GET /current/events/search/?workspace_id={id}&category=ai
```
**Who downloaded files from a share:**
```
GET /current/events/search/?share_id={id}&event=share_storage_download_token_created
```
#### AI-Powered Summaries
Request a natural language recap of recent activity with `GET /current/events/search/summarize/`. Returns event counts,
category breakdowns, and a narrative summary. Focus the summary on a specific workspace or share, or summarize across
the entire org.
**Agent use case — stay in sync:** You manage a workspace with 10,000 files. Instead of listing the entire directory
tree to find what changed, query events since your last check. You get a precise list: "3 files uploaded, 1 renamed,
2 new members added" — with timestamps, actors, and affected resources.
**Agent use case — react to changes:** A client uploads tax documents to a Receive share. The events feed shows the
upload immediately. Your agent detects it, processes the documents, and notifies the accountant — no polling the file
list required.
**Agent use case — report to humans:** A human asks "What happened on the project this week?" You call the AI summary
endpoint scoped to their workspace and return a clean narrative report — no log parsing required.
### 13. Activity Polling — Wait for Changes Efficiently
After triggering an async operation (uploading a file, enabling intelligence, creating a share), don't loop on the
resource endpoint to check if it's done. Instead, use the activity long-poll endpoint:
`GET /current/activity/poll/{entity_id}?wait=95&lastactivity={timestamp}`
The `{entity_id}` is the profile ID of the resource you're watching — a workspace ID, share ID, or org ID. For
**upload sessions**, use the **user ID** (since uploads are user-scoped, not workspace-scoped until the file is added
to storage).
The server holds the connection open for up to 95 seconds and returns **immediately** when something changes on that
entity — file uploads complete, previews finish generating, AI indexing completes, comments are added, etc.
The response includes activity keys that tell you *what* changed (e.g., `storage:{fileId}` for file changes,
`preview:{fileId}` for preview readiness, `ai_chat:{chatId}` for chat updates, `ai_state:{fileId}` for AI indexing
state changes, `upload:{uploadId}` for upload completion). Pass the returned `lastactivity` timestamp into your next
poll to receive only newer changes.
This gives you near-instant reactivity with a single open connection per entity, instead of hammering individual
endpoints.
**WebSocket upgrade:** For true real-time delivery (~300ms latency vs ~1s for polling), connect via WebSocket at
`wss://{host}/api/websocket/?token={auth_token}`. The server pushes activity arrays as they happen:
```json
{"response": "activity", "activity": ["storage:2abc...", "preview:2abc..."]}
```
You then fetch only the resources that changed. If the WebSocket connection fails, fall back to long-polling — the data
is identical, just slightly higher latency.
**Agent use case:** You upload a 500-page PDF and need to know when AI indexing is complete before querying it. Instead
of polling the file details endpoint every few seconds, open a single long-poll on the workspace. When
`ai_state:{fileId}` appears in the activity response, the file is indexed and ready for AI chat.
### 14. Metadata — Structured Data on Files
The metadata system lets agents attach structured, typed key-value data to files. This goes beyond filenames and
timestamps — you can store invoice amounts, contract parties, document categories, or any domain-specific fields, then
query and sort files by those fields.
#### Architecture
The system has three layers:
1. **Templates** — define a metadata schema: named fields with types (`string`, `int`, `float`, `bool`, `json`, `url`,
`datetime`), constraints (`min`, `max`, `fixed_list`), and descriptions. Templates belong to a workspace and are
grouped by category (`legal`, `financial`, `business`, `medical`, `technical`, `engineering`, `insurance`,
`educational`, `multimedia`, `hr`).
2. **Template Assignments** — bind a single template to a workspace. All files in the workspace inherit that template
automatically. One template per workspace — assigning a new template replaces the previous one. This keeps resolution
simple and efficient (a single lookup instead of a tree-walk).
3. **Node Metadata** — the actual key-value pairs stored on individual files. Each file's metadata is split into
**template metadata** (conforming to the resolved template's field definitions) and **custom metadata** (user-defined
fields not tied to any template).
#### Template Management
| Endpoint | Description |
|----------|-------------|
| `GET /current/metadata/templates/categories/` | List available template categories |
| `POST /current/workspace/{id}/metadata/templates/` | Create a template (name, description, category, fields JSON) |
| `DELETE /current/workspace/{id}/metadata/templates/` | Delete a template |
| `GET /current/workspace/{id}/metadata/templates/list/` | List templates (sub-paths: `all`, `custom`, `system`, `enabled`, `disabled`) |
| `GET /current/workspace/{id}/metadata/templates/{template_id}/details/` | Get template details with all fields |
| `POST /current/workspace/{id}/metadata/templates/{template_id}/settings/` | Enable/disable, set priority (1-5) |
| `POST /current/workspace/{id}/metadata/templates/{template_id}/update/` | Update definition (append `/create/` to copy) |
#### Template Assignment & Resolution
| Endpoint | Description |
|----------|-------------|
| `POST /current/workspace/{id}/metadata/template/assign/` | Assign template to the workspace (one per workspace) |
| `DELETE /current/workspace/{id}/metadata/template/unassign/` | Remove the workspace template assignment |
| `GET /current/workspace/{id}/metadata/template/resolve/{node_id}/` | Resolve the workspace template (`node_id` accepted for compat, ignored) |
| `GET /current/workspace/{id}/metadata/template/assignments/` | List the workspace template assignment |
#### Node Metadata Operations
| Endpoint | Description |
|----------|-------------|
| `GET /current/workspace/{id}/storage/{node_id}/metadata/details/` | Get all metadata (`template_metadata` + `custom_metadata`) |
| `POST /current/workspace/{id}/storage/{node_id}/metadata/update/{template_id}/` | Set/update key-value pairs |
| `DELETE /current/workspace/{id}/storage/{node_id}/metadata/` | Delete metadata keys |
| `POST /current/workspace/{id}/storage/{node_id}/metadata/extract/` | AI-extract metadata from file content (documents, images, code) |
| `POST /current/workspace/{id}/storage/{node_id}/metadata/extract-all/` | Batch-extract metadata for all files in a folder (async, returns job_id) |
| `GET /current/workspace/{id}/storage/{node_id}/metadata/list/{template_id}/` | List files with metadata for a template |
| `GET /current/workspace/{id}/storage/{node_id}/metadata/templates/` | List templates in use across files |
| `GET /current/workspace/{id}/storage/{node_id}/metadata/versions/` | Metadata version history |
#### Saved Views
Saved views persist filter/sort configurations for browsing metadata across files in a spreadsheet-like interface.
| Endpoint | Description |
|----------|-------------|
| `POST /current/workspace/{id}/storage/{node_id}/metadata/view/` | Create or update a saved view |
| `DELETE /current/workspace/{id}/storage/{node_id}/metadata/view/` | Delete a saved view |
| `GET /current/workspace/{id}/storage/{node_id}/metadata/views/` | List all saved views |
#### AI-Powered Extraction
Metadata extraction works in three modes:
1. **Automatic (during ingestion)** — when intelligence is enabled and a template is assigned to the workspace, every
file uploaded is automatically extracted against the template schema during the ingestion pipeline. No API call
needed — metadata appears on the file after ingestion completes. This includes documents, spreadsheets, images
(PNG, JPEG, WebP up to 30 MB), and code files.
2. **Manual (per file)** — the extract endpoint (`POST .../metadata/extract/`) resolves the workspace template, reads
the file content, and uses AI to populate the template fields. You can optionally pass `template_id` to override the
workspace template. Extraction is synchronous — the response includes the extracted metadata immediately.
3. **Batch (per folder)** — the extract-all endpoint (`POST .../metadata/extract-all/`) enqueues an async job that
processes every file in a folder against the workspace template. Returns a `job_id` for tracking. Rate-limited to
2 requests/minute, 10/hour. Use this when you assign a template to a workspace that already contains files.
A daily background process also detects stale metadata — files whose extraction predates the template's last update —
and automatically re-extracts them, ensuring metadata stays current when templates evolve.
For example, uploading an invoice to a workspace with a "financial" template automatically fills in fields like
`invoice_number`, `amount`, `vendor_name`, and `due_date` — no extraction call required if intelligence is enabled.
#### Field Definition Structure
When creating templates, each field in the `fields` JSON array supports:
| Property | Type | Description |
|----------|------|-------------|
| `name` | string | Field identifier (alphanumeric + underscore) |
| `description` | string | Human-readable description |
| `type` | string | `string`, `int`, `float`, `bool`, `json`, `url`, `datetime` |
| `min` | number | Minimum value constraint |
| `max` | number | Maximum value constraint |
| `default` | mixed | Default value |
| `fixed_list` | array | Allowed values (dropdown) |
| `can_be_null` | bool | Whether null is allowed |
#### Agent Use Cases
- **Automatic classification:** Assign a template to the workspace, enable intelligence, upload files. Every file gets
structured metadata extracted automatically during ingestion — no manual extraction calls needed.
- **Data pipeline:** Create a workspace with an invoice template assigned. Upload invoices — metadata (amounts, vendors,
dates) is extracted automatically. Query by field values using the list endpoint.
- **Compliance tracking:** Create a template with required fields (review_date, reviewer, status). Assign to the
workspace. The metadata view shows which files are missing required fields at a glance.
- **Bulk backfill:** Assign a template to a workspace that already has files, then use `extract-all` on each folder to
batch-extract metadata for existing content. The daily staleness walker re-extracts when templates are updated.
- **Custom + template fields:** Files support both template metadata (structured, schema-enforced) and custom metadata
(user-defined, ad-hoc). Use template fields for consistent extraction and custom fields for one-off annotations.
### 15. Reference Values — Enums & Constraints
This section lists valid values for commonly used parameters across the API.
#### Preview Types
Valid `preview_type` values (used in preview read/preauthorize endpoints):
`thumbnail`, `image`, `hlsstream`, `pdf`, `spreadsheet`
Preview states returned in file details: `unknown`, `not possible`, `not generated`, `error`, `in progress`, `ready`
#### Image Transformations
The `transform_name` in transform endpoints is `image`. Supported query parameters:
| Parameter | Values | Description |
|-----------|--------|-------------|
| `output-format` | `png`, `jpg` | Output image format |
| `width`, `height` | pixels | Resize dimensions |
| `cropwidth`, `cropheight` | pixels | Crop region size |
| `cropx`, `cropy` | pixels | Crop region origin |
| `rotate` | `0`, `90`, `180`, `270` | Rotation angle |
| `size` | `IconSmall`, `IconMedium`, `Preview` | Predefined size presets |
Transformation states: `rendered`, `rendering`, `unrendered`, `unable to render`
#### AI File States
When intelligence is enabled, each file progresses through AI processing states (visible in node details `ai.state`):
`disabled` → `pending` → `inprogress` → `ready` (or `failed`)
#### AI Chat Parameters
| Parameter | Constraint |
|-----------|-----------|
| `type` | `chat` or `chat_with_files` |
| `personality` | `concise`, `detailed` (default) |
| `privacy` / `visibility` | `private`, `public` (default: `public`) |
| `name` | Max 100 characters |
| `question` | Max 12,768 characters |
| `files_attach` | Max 20 files, 200 MB total |
| `files_scope` | Max 100 `nodeId:versionId` pairs |
#### Quick Share Constraints
- Single file only, max 1 GB
- Default expiration: 3 hours, maximum: 24 hours
- Auto-deleted on expiration, public access (no auth)
- Can update expiration but not beyond the original 24-hour window
#### Download Tokens
Use `GET .../storage/{node_id}/requestread/` to generate a temporary auth-free download token. Pass the returned
`token` as a query parameter: `GET .../storage/{node_id}/read/?token={token}`. This is useful for opening files in
browser tabs without sending Authorization headers.
**MCP agents** have additional download options: use the `download://` resource templates for direct content retrieval
(up to 50 MB), or the `/file/` HTTP pass-through endpoint for streaming larger files. See the "MCP Tool Architecture"
section for details.
#### Unit Calculations
- **Storage** is measured in GibiBytes (1024^3 bytes)
- **Bandwidth** is measured in GigaBytes (1000^3 bytes)
---
## Agent Plan — What's Included (Free)
The agent plan is a free tier designed to get agents started. It's intentionally lightweight — enough to build and
demonstrate value, with room to grow when the org transfers to a human on a paid plan.
| Resource | Included |
|---------------------------|-----------------------------------------------------|
| **Price** | $0 — no credit card, no trial period, no expiration |
| **Storage** | 50 GB |
| **Max file size** | 1 GB |
| **Monthly credits** | 5,000 (resets every 30 days) |
| **Workspaces** | 5 |
| **Shares** | 50 |
| **Members per workspace** | 5 |
| **Share invitations** | 10 per share |
| **Account auto-deletion** | Never |
### What Credits Cover
All platform activity consumes credits from the monthly 5,000 allowance:
| Resource | Cost |
|-------------------------|-------------------------|
| Storage | 100 credits/GB |
| Bandwidth | 212 credits/GB |
| AI chat tokens | 1 credit per 100 tokens |
| Document pages ingested | 10 credits/page |
| Video ingested | 5 credits/second |
| Audio ingested | 0.5 credits/second |
| Images ingested | 5 credits/image |
| File conversions | 25 credits/conversion |
When credits run out, the org enters a reduced-capability state — file storage and access continue to work, but
credit-consuming operations (AI chat, file ingestion, bandwidth-heavy downloads) are limited until the 30-day reset.
The org is never deleted.
**When you hit the credit limit:** The recommended path is to transfer the org to a human user who can upgrade to a
paid plan with unlimited credits. See "Ownership Transfer" above. If the agent account is using a human account type
(not recommended), direct the user to upgrade at `https://go.fast.io/onboarding` or via the billing API.
### After Transfer — Human Plan Options
Once an agent transfers an org to a human, they get the free plan (credit-based, no trial period) and can upgrade:
| Feature | Agent (Free) | Free (Human) | Pro | Business |
|-----------------|--------------|--------------|-----------|-----------|
| Monthly credits | 5,000 | 5,000 | Unlimited | Unlimited |
| Storage | 50 GB | 50 GB | 1 TB | 5 TB |
| Max file size | 1 GB | 1 GB | 25 GB | 50 GB |
| Workspaces | 5 | 5 | 10 | 1,000 |
| Shares | 50 | 50 | 1,000 | 50,000 |
The transfer flow is the primary way agents deliver value — and the only way to upgrade beyond the agent plan. Set
everything up on the free agent plan, transfer ownership when the work is complete or when credits are exhausted, and
the human upgrades when they're ready. The agent retains admin access to keep managing things.
---
## Common Workflows
### Deliver a Report to a Client
1. Upload report PDF to workspace
2. Create a Send share with password protection and 30-day expiration
3. Share the link with the client
4. Client sees a branded page, previews the PDF inline, downloads if needed
5. You get a notification when they access it
### Collect Documents From a User
1. Create a Receive share ("Upload your tax documents here")
2. Share the link
3. User uploads files through a clean, branded interface
4. Files appear in your workspace, auto-indexed by AI (if intelligence is on)
5. Ask the AI: "Are all required forms present?"
### Build a Knowledge Base
1. Create a workspace **with intelligence enabled** (this is one of the workflows that justifies the ingestion cost)
2. Upload all reference documents
3. AI auto-indexes and summarizes everything on upload
4. Use **semantic search** (`ai/search`) for fast, low-cost retrieval — find relevant document chunks by meaning without an LLM round-trip. Best for lookup, recall, and memory workflows
5. Use **AI chat** (`chat_with_files`) when you need the LLM to synthesize, analyze, or summarize across documents — returns a natural language answer with citations
6. Combine both: search first to find relevant content cheaply, then chat only when synthesis is needed
### Set Up an Agentic Team Workspace
1. Create org + workspace + folder structure
2. Upload templates and reference docs
3. Invite other agents and human team members
4. Create shares for client deliverables (Send) and intake (Receive)
5. Configure branding, passwords, expiration
6. Transfer ownership to a human when ready — they get a fully configured platform, agents keep admin access
### Collaborative Review Cycle (Exchange Share)
1. Create an Exchange share ("Review these designs and upload your feedback")
2. Upload draft files for the recipient
3. Share the link — recipient can both download your files and upload theirs
4. Comments and annotations on files enable inline feedback
5. AI summarizes what changed between rounds (if intelligence is on)
### Extract Structured Metadata From Documents
1. Create a workspace **with intelligence enabled** (metadata extraction requires ingestion — budget for ingestion costs)
2. Create a metadata template with the fields you need (e.g., invoice_number, amount, vendor, due_date)
3. Assign the template to the workspace (`POST .../metadata/template/assign/`)
4. Upload files — metadata is automatically extracted during ingestion against the template schema
5. For existing files, use `POST .../metadata/extract-all/` on each folder to batch-extract
6. Query files by metadata fields using the list endpoint, or view in the spreadsheet-like metadata view
7. Custom fields can be added to any file independently of the template
### One-Off Document Analysis (No Intelligence Needed)
1. Create a workspace (intelligence off is fine)
2. Upload the files you want to analyze
3. Create an AI chat and attach the specific files directly (up to 20 files)
4. Ask questions — AI reads the attachments and responds with citations
5. No persistent indexing, no credit cost for ingestion
### Choose Between Room and Shared Folder
**Use a Room (independent storage) when:**
- Delivering final, immutable outputs (reports, compliance packages)
- You want a snapshot that won't change if workspace files are updated
- Files are "done" and shouldn't reflect future edits
**Use a Shared Folder (workspace-backed) when:**
- Files are actively being updated (live data feeds, ongoing projects)
- You want zero storage duplication
- Recipients should always see the latest version
### Manage Credit Budget
1. Check current usage: `GET /current/org/{org_id}/billing/usage/limits/credits/`
2. Storage costs 100 credits/GB — a 10 GB workspace costs 1,000 credits/month
3. Document ingestion costs 10 credits/page — a 50-page PDF costs 500 credits
4. Disable intelligence on storage-only workspaces to avoid ingestion costs
5. Use attach-only AI chat (no intelligence needed) for one-off analysis to save credits
6. When credits run low, transfer the org to a human who can upgrade to unlimited credits
---
## MCP Tool Architecture
The MCP server exposes **19 consolidated tools**, each covering a domain. Every tool uses an `action` parameter to
select the specific operation — agents don't need to discover hundreds of separate tools, just 19 tools with clearly
named actions.
| Tool | Domain | Example Actions |
|--------------|---------------------------------|-------------------------------------------------------------------------------|
| `auth` | Authentication | `signin`, `signup`, `set-api-key`, `pkce-login`, `pkce-complete`, `status`, `signout` |
| `org` | Organizations | `list`, `details`, `create`, `update`, `discover-all` |
| `workspace` | Workspaces & metadata | `list`, `details`, `create`, `update`, `check-name`, plus 17 `metadata-*` actions for template management, node metadata CRUD, AI extraction, and saved views |
| `share` | Shares | `list`, `create`, `update`, `delete`, `quickshare-create` |
| `storage` | Files, folders, locks, previews | `list`, `details`, `search`, `create-folder`, `create-note`, `move`, `delete`, `lock-acquire`, `lock-status`, `lock-release`, `preview-url` (returns constructed `preview_url`), `preview-transform` (returns constructed `transform_url`) |
| `upload` | File uploads | `create-session`, `stage-blob`, `chunk`, `finalize`, `text-file`, `web-import` |
| `download` | Downloads | `file-url`, `zip-url`, `quickshare-details` |
| `ai` | AI chat and semantic search (scope defaults to entire workspace — omit scope params to search all indexed documents). Folder scope expands subfolder tree only — documents within scoped folders are searched automatically by RAG, not enumerated individually. | `chat-create`, `message-send`, `message-read`, `chat-list`, `search` |
| `member` | Members | `add`, `update`, `remove`, `details` |
| `invitation` | Invitations | `list`, `send`, `revoke`, `accept-all` |
| `asset` | Branding assets | `types`, `list`, `upload`, `delete` |
| `comment` | Comments | `list`, `create`, `details`, `delete` |
| `event` | Events & audit | `search`, `details`, `summarize`, `activity-poll` |
| `user` | Account mgmt | `me`, `update`, `invitation-list`, `allowed` |
| `task` | Task lists & tasks | `list-lists`, `create-list`, `list-details`, `update-list`, `delete-list`, `list-tasks`, `create-task`, `task-details`, `update-task`, `delete-task`, `change-status`, `assign-task`, `bulk-status`, `reorder-tasks`, `reorder-lists` |
| `todo` | Todo checklists | `list`, `create`, `details`, `update`, `delete`, `toggle`, `bulk-toggle` |
| `approval` | Approval workflows | `list`, `create`, `details`, `resolve` |
| `worklog` | Activity logs & interjections | `list`, `append`, `interject`, `details`, `acknowledge`, `unacknowledged` |
| `apps` | Apps discovery | `list` |
### `web_url` in Tool Responses — Use It Instead of Building URLs
All entity-returning tool responses include a `web_url` field containing a ready-to-use link to the resource in the Fast.io web UI.
**Use `web_url` directly** instead of constructing URLs manually from API response fields. This avoids errors from
slug generation, subdomain routing, or parameter formatting.
Tools that return `web_url`:
| Tool | Actions |
|------|---------|
| `org` | `list`, `details`, `create`, `update`, `public-details`, `list-workspaces`, `list-shares`, `create-workspace`, `transfer-token-create`, `transfer-token-list`, `discover-all`, `discover-available`, `discover-external` |
| `workspace` | `list`, `details`, `update`, `available`, `list-shares`, `create-note`, `update-note`, `quickshare-get`, `quickshares-list` |
| `share` | `list`, `details`, `create`, `update`, `public-details`, `available` |
| `storage` | `list`, `details`, `search`, `trash-list`, `create-folder`, `copy`, `move`, `rename`, `restore`, `add-file`, `version-list`, `version-restore`, `preview-url`, `preview-transform` |
| `ai` | `chat-create`, `chat-details`, `chat-list` |
| `upload` | `text-file`, `finalize` |
| `download` | `file-url`, `quickshare-details` |
When presenting links to users, always use `web_url` from tool responses. Never construct URLs manually.
**Resources** available via `resources/read`:
- `skill://guide` — full tool documentation with parameters and examples
- `session://status` — current authentication state
- `download://workspace/{workspace_id}/{node_id}` — download a workspace file (returns base64 content up to 50 MB)
- `download://share/{share_id}/{node_id}` — download a share file (returns base64 content up to 50 MB)
- `download://quickshare/{quickshare_id}` — download a quickshare file (public, no auth required, up to 50 MB)
The `download://` resource templates provide direct file content retrieval via the MCP `resources/read` protocol.
Files up to 50 MB are returned inline as base64 blobs. Larger files return a fallback message directing to the HTTP
pass-through endpoint (see below). The `download` tool's `file-url` and `quickshare-details` actions include a
`resource_uri` field in their response that points to the corresponding `download://` resource URI.
**HTTP pass-through endpoint** for file downloads:
The MCP server exposes a `/file/` HTTP endpoint that streams file content directly with proper `Content-Type`,
`Content-Length`, and `Content-Disposition` headers — useful for large files that exceed the 50 MB MCP resource limit
or when streaming is preferred over base64 encoding.
| Path | Auth | Description |
|------|------|-------------|
| `GET /file/workspace/{workspace_id}/{node_id}` | `Mcp-Session-Id` header required | Stream a workspace file |
| `GET /file/share/{share_id}/{node_id}` | `Mcp-Session-Id` header required | Stream a share file |
| `GET /file/quickshare/{quickshare_id}` | None (public) | Stream a quickshare file |
For workspace and share downloads, include the `Mcp-Session-Id` header from your active MCP session. The server uses
the session's auth token to fetch the file and streams it back.
**Query parameters:**
- `?error=html` — returns error pages as HTML instead of JSON (useful for browser-facing links)
**Size limits:** The `download://` resource templates return file content inline (base64) for files up to **50 MB**.
Larger files return a fallback message directing to the `/file/` HTTP pass-through endpoint.
**`web_url` in download responses:** The `download` tool's `file-url` and `quickshare-details` actions include both
a `resource_uri` (for MCP resource reads) and a `web_url` (for browser-facing links) in their responses.
**Resource completion** — The workspace and share `download://` resource templates support MCP `completion/complete`
for tab-completion of IDs. Agents can use this to discover valid workspace IDs, share IDs, and node IDs without
needing to call separate list actions first.
### Tool Annotations — Safety & Side Effects
All 19 tools include explicit MCP annotations (`title`, `readOnlyHint`, `destructiveHint`, `idempotentHint`,
`openWorldHint`) so agents and agent frameworks can make informed decisions about confirmation prompts, retries, and
automated execution.
**Read-only tools** (safe, no confirmation needed, `idempotentHint: true`):
- `download`, `event`, `apps` — these tools only read data, never modify state, and are safe to retry
**Non-destructive mutation tools** (create or update, no delete actions):
- `upload`, `invitation`, `worklog` — these tools create or modify resources but cannot delete them
**Destructive tools** (include delete, purge, or close actions — require user confirmation):
- `auth`, `user`, `org`, `workspace`, `share`, `storage`, `ai`, `comment`, `member`, `asset`, `task`, `todo`, `approval` — these tools have at
least one action that permanently removes or closes a resource. Agent frameworks should prompt for confirmation before
executing destructive actions.
**Discovery tools** (`openWorldHint: true`):
- `org`, `user`, `workspace`, `share`, `storage` — these tools can discover resources beyond the agent's current
context. Agents may encounter resources they haven't seen before in list/search results.
**Credit-consuming operations** to be aware of:
- AI chat: 1 credit per 100 tokens
- File uploads: storage credits (100 credits/GB)
- Downloads: bandwidth credits (212 credits/GB)
- Document ingestion: 10 credits/page (when intelligence is enabled) — this can be the largest credit consumer. A 100-page document costs 1,000 credits to ingest.
### Code Mode — Streamlined Tools for Headless Agents
The MCP server (v2026.02.102+) detects the connecting client and serves one of two tool sets:
**Named Mode** (Claude Desktop, Cline, unknown clients): All 19 core tools listed above plus 12 app-specific widget
tools — the full interactive experience with action-based routing across every domain.
**Code Mode** (Claude Code, Cursor, Continue): 4 tools optimized for programmatic workflows:
| Tool | Purpose |
|------------|---------------------------------------------------------------------------------------------|
| `auth` | Authentication — same as Named Mode (`signin`, `signup`, `set-api-key`, `pkce-login`, etc.) |
| `upload` | File uploads — same as Named Mode (`create-session`, `chunk`, `finalize`, `text-file`, etc.)|
| `search` | Keyword/tag search over 285 API endpoints |
| `execute` | Make authenticated API calls to Fast.io (structured method/path/body/params) |
#### `search` Tool
Discovers API endpoints by keyword and tag. Returns scored matches with method, path, summary, parameters, and relevant
concept docs (pagination, error codes, etc.).
**Parameters:**
| Parameter | Type | Required | Description |
|--------------------|---------|----------|----------------------------------------------------------------|
| `query` | string | Yes | Keyword search query (e.g., "list workspaces", "upload file") |
| `tag` | string | No | Filter results by API tag (e.g., "workspace", "storage", "ai") |
| `include_concepts` | boolean | No | Include related concept docs (pagination, error codes, etc.) |
| `max_results` | number | No | Maximum number of endpoint matches to return |
#### `execute` Tool
Makes authenticated API calls to the Fast.io API using structured parameters. The tool automatically injects the
session token, unwraps the API response envelope, and extracts errors — agents receive clean response data without
boilerplate. Non-JSON responses (text, binary) are handled gracefully.
**Parameters:**
| Parameter | Type | Required | Description |
|--------------|--------|----------|--------------------------------------------------------------------|
| `method` | enum | Yes | HTTP method: `get`, `post`, `postJson`, `delete`, `put` |
| `path` | string | Yes | API endpoint path (e.g., `/current/org/{id}/list/workspaces/`) |
| `body` | object | No | Request body (for `post`, `postJson`, `put`) |
| `params` | object | No | Query string parameters |
| `timeout_ms` | number | No | Request timeout in milliseconds |
**Special paths:**
| Path | Purpose |
|--------------------------------|---------------------------------------------------|
| `/readnote/` | Read note content in code mode |
| `download://{file_id}` | MCP resource path for reading file content |
#### Code Mode Workflow Pattern
Code Mode agents follow a **search → review → execute → iterate** loop:
1. **Search** — use the `search` tool to discover relevant API endpoints by keyword or tag
2. **Review** — examine the returned endpoint details (method, path, parameters, summary)
3. **Execute** — call the endpoint with structured parameters (`method`, `path`, `body`, `params`)
4. **Iterate** — refine based on results, search for additional endpoints as needed
This pattern replaces the need for 19+ individually named tools. Agents discover endpoints dynamically via search and
call them with structured parameters via execute, without needing pre-registered tool definitions for each operation.
**Example — list workspaces in an org:**
```
// Search: search tool with query "list workspaces"
// → returns: GET /current/org/{id}/list/workspaces/
// Execute:
execute method="get" path="/current/org/{org_id}/list/workspaces/"
```
### Response Hints — Guided Agent Workflows
Tool responses include structured hints that help agents navigate multi-step workflows, handle errors gracefully, and
understand resource state. Agents should read and act on these hints rather than guessing the next step.
**`_next` — Suggested next actions:**
Successful tool responses include a `_next` array of contextual next-step suggestions using exact tool names, action
names, and IDs from the response. Agents should follow these hints instead of guessing the next step or consulting
docs. Present on approximately 30 actions across all tools.
Example: after `storage` action `list`, `_next` might suggest `["storage folder-details {node_id}",
"download file-url {node_id}", "ai chat"]` with actual IDs from the response populated in the suggestions.
**`_warnings` — Destructive or gated action warnings:**
Actions that are destructive, irreversible, or have significant side effects include `_warnings` strings in their
response. Agents should read these warning
... (truncated)
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "dbalve",
"slug": "fast-io",
"displayName": "Fast.io",
"latest": {
"version": "1.121.0",
"publishedAt": 1773234902457,
"commit": "https://github.com/openclaw/skills/commit/48b49d0c38adeec71368e963a695a919949b925d"
},
"history": [
{
"version": "1.105.0",
"publishedAt": 1772149097549,
"commit": "https://github.com/openclaw/skills/commit/d614a8147a4ca345a829a2af039ea6a3f2a38efd"
},
{
"version": "1.94.1",
"publishedAt": 1771879411090,
"commit": "https://github.com/openclaw/skills/commit/862f012160ac91bfcb2eb325d4529a3a9ef7c2f3"
},
{
"version": "1.73.0",
"publishedAt": 1771425837078,
"commit": "https://github.com/openclaw/skills/commit/2b020c6b0a69e653eaa3048e893500e261ff0dc3"
},
{
"version": "1.68.0",
"publishedAt": 1771275195927,
"commit": "https://github.com/openclaw/skills/commit/1eeb97be55440b1e17527f4c4520b524c1fdb10a"
},
{
"version": "1.64.0",
"publishedAt": 1771102216637,
"commit": "https://github.com/openclaw/skills/commit/b98048440c7f33cc0486bd1a70416bdfc95f5ea0"
},
{
"version": "1.54.0",
"publishedAt": 1771009791944,
"commit": "https://github.com/openclaw/skills/commit/c2114a107f6aa6ad63808dec5091b3703e53e6e2"
},
{
"version": "1.43.0",
"publishedAt": 1770664071058,
"commit": "https://github.com/openclaw/skills/commit/b1664676559aaa230f067730322b792302c69fa6"
},
{
"version": "1.41.0",
"publishedAt": 1770578485503,
"commit": "https://github.com/openclaw/skills/commit/901c2eb2f9ebee407e6ae3fd8bb35d0cb95f52b1"
},
{
"version": "1.39.1",
"publishedAt": 1770480469231,
"commit": "https://github.com/openclaw/skills/commit/78de69abc7345251d476f2933d2d3fff02c8aa21"
},
{
"version": "1.35.0",
"publishedAt": 1770399426618,
"commit": "https://github.com/openclaw/skills/commit/a49cda03c79cf4fb852fe6bb92c1a38192c2c3a2"
},
{
"version": "1.25.0",
"publishedAt": 1770317286569,
"commit": "https://github.com/clawdbot/skills/commit/9d6e0ef63020f09f6e080f419bcec55f22b315f1"
},
{
"version": "1.20.0",
"publishedAt": 1770244700813,
"commit": "https://github.com/clawdbot/skills/commit/69f9aeb118057496caa6937e35a5f8f86125ab92"
}
]
}
```