Events & Activity Event search, activity polling, WebSocket realtime.

Base URL: https://api.fast.io/current/ Auth: Bearer {jwt_token} Format: JSON

Events capture every action in the system — file operations, membership changes, comments, AI activity, billing, workflow, and more. Use the event search endpoints to query the log, activity polling for efficient change detection, and WebSocket for real-time delivery.

Search and filter the event log. Events capture every action in the system — file operations, membership changes, comments, AI activity, billing, workflow, and more.

Search Events

GET /current/events/search/

Search and filter events with comprehensive filtering options. Uses offset-based pagination.

Auth: Required (JWT). Rate limited: 5 per 3s, 15 per 30s, 120 per 10min.

Query Parameters

ParameterTypeRequiredDefaultDescription
user_id string Conditional Filter by user profile ID. One of user_id, org_id, workspace_id, share_id, or parent_event_id is required.
org_id string Conditional Filter by organization profile ID
workspace_id string Conditional Filter by workspace profile ID
share_id string Conditional Filter by share profile ID
parent_event_id string Conditional Filter by parent event ID for serial/batch events. Cannot combine with filters other than acknowledged, limit, offset.
event string No Filter by specific event name (e.g., workspace_storage_file_added). Max 100 characters.
category string No Filter by event category. See Event Categories.
subcategory string No Filter by event subcategory. See Event Subcategories.
calling_user_id string No Filter by the user who triggered the event (19-digit numeric ID)
object_id string No Filter by related object ID (file, folder, etc.)
acknowledged string No Filter by acknowledgment status: "true" or "false"
visibility string No All non-internal "external_audit_log" or "external"
created-min string No Lower bound for event creation time. Accepts ISO 8601 (e.g., 2025-12-01T06:00:00Z) or YYYY-MM-DD HH:MM:SS
created-max string No Upper bound for event creation time. Same format as created-min; must be > created-min
limit integer No 100 Maximum number of results (1–250)
offset integer No 0 Number of results to skip for pagination
output string No Select the response shape. Comma-separated tokens (e.g. terse, standard, full). See the "Compact Responses" section below for the three detail levels and the fields returned at each level.

Profile filter priority: If multiple profile filters are supplied, priority is: user_id > org_id > workspace_id > share_id. Only the highest-priority filter is applied.

Example Request

curl -X GET "https://api.fast.io/current/events/search/?workspace_id=12345678901234567890&category=workspace&subcategory=storage&limit=50" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "events": [
      {
        "event_id": "evt_abc123xyz789",
        "created": "2025-01-20 10:30:45",
        "acknowledged": false,
        "event": "workspace_storage_file_added",
        "category": "workspace",
        "sub_category": "storage",
        "object_id": "node_def456ghi789",
        "calling_user": "98765432109876543210",
        "calling_user_name": "Jane Smith",
        "org_id": "11111111111111111111",
        "workspace_id": "12345678901234567890",
        "filename": "quarterly_report.pdf",
        "file_size": 2485760
      }
    ]
  }
}

Response Fields

FieldTypeDescription
resultstring"yes" on success
response.eventsarrayArray of event objects
response.events[].event_idstringUnique event identifier (alphanumeric OpaqueId)
response.events[].createdstringEvent timestamp in Y-m-d H:i:s format
response.events[].acknowledgedbooleanWhether the current user has acknowledged this event
response.events[].eventstringEvent name identifier (e.g., workspace_storage_file_added)
response.events[].categorystringEvent category name
response.events[].sub_categorystringEvent subcategory name
response.events[].object_idstringRelated object OpaqueId (if applicable)
response.events[].calling_userstring19-digit numeric ID of the triggering user
response.events[].calling_user_namestringDisplay name of the triggering user
response.events[].org_idstringOrganization ID context (if applicable)
response.events[].workspace_idstringWorkspace ID context (if applicable)
response.events[].share_idstringShare ID context (if applicable)
response.events[].user_idstringTarget user ID for user-specific events (if applicable)

Additional event-specific fields (e.g., filename, file_size, member_name) vary by event type.

Error Responses

Error CodeHTTP StatusDescription
1605 (Invalid Input)400No profile filter or parent_event_id provided
1605 (Invalid Input)400created-min is greater than created-max
1605 (Invalid Input)400parent_event_id combined with disallowed filters
1680 (Access Denied)403Token scope does not include the requested profile
1600 (Query Error)500Internal error during event search
1650 (Authentication Invalid)401Missing or invalid JWT token
1651 (Invalid Request Type)400Wrong HTTP method (only GET accepted)

Notes: Results may be slightly delayed due to caching. OAuth scoped tokens enforce entity-level access: events are filtered to only entities within the token's scope. Events the user cannot access are automatically excluded from results.


Summarize Events (AI)

GET /current/events/search/summarize/

Search events and generate an AI-powered natural language summary. Accepts all parameters from /events/search/ plus user_context.

Auth: Required (JWT). Shares the search rate limit.

Additional Query Parameters

ParameterTypeRequiredDefaultDescription
user_context string No "" Focus guidance for the AI summary (e.g., "Focus on uploads"). Max 64 chars; letters, numbers, spaces, . , ! ? ' - only.

All other parameters are identical to Search Events.

Example Request

curl -X GET "https://api.fast.io/current/events/search/summarize/?workspace_id=12345678901234567890&user_context=Focus%20on%20file%20uploads&limit=100" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "summary": {
      "text": "@[user:98765432109876543210:Jane Smith] uploaded 12 files...",
      "metrics": {
        "total_events": 50,
        "unique_actors": 5,
        "date_range": {
          "start": "2025-01-01T00:00:00+00:00",
          "end": "2025-01-20T10:30:45+00:00"
        },
        "categories": {
          "storage": 30,
          "members": 20
        }
      }
    },
    "events": [ ... ]
  }
}

Response Fields (additional to events search)

FieldTypeDescription
response.summaryobject|nullAI-generated summary, or null if no events or generation failed
response.summary.textstringNatural language summary with @[type:ID:name] mention pills
response.summary.metrics.total_eventsintegerTotal events summarized
response.summary.metrics.unique_actorsintegerDistinct users who triggered events
response.summary.metrics.date_range.startstringEarliest event timestamp (YYYY-MM-DD HH:MM:SS)
response.summary.metrics.date_range.endstringMost recent event timestamp (YYYY-MM-DD HH:MM:SS)
response.summary.metrics.categoriesobjectMap of category names to event counts

Summary Mention Pill Formats

EntityFormatExample
User@[user:USER_ID:Display Name]@[user:98765432109876543210:Jane Smith]
File@[file:FILE_ID:filename.ext]@[file:node_abc123:report.pdf]
Folder@[folder:FOLDER_ID:foldername]@[folder:node_def456:Projects]
Workspace@[workspace:WS_ID:name]@[workspace:12345678901234567890:Engineering]
Share@[share:SHARE_ID:name]@[share:55555555555555555555:Client Files]

Notes: Summary generation failures are non-fatal: summary is null but events are still returned. Requires a billable organization for AI token billing (resolved from profile context).


Event Details

GET /current/event/{event_id}/details/

Get full details for a single event.

Auth: Required (JWT). Default rate limiting. No credit consumption.

Path Parameters

ParameterTypeRequiredDescription
{event_id} string Yes Alphanumeric OpaqueId of the event

Example Request

curl -X GET "https://api.fast.io/current/event/evt_abc123xyz789/details/" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "event": {
      "event_id": "evt_abc123xyz789",
      "created": "2025-01-20 10:30:45",
      "acknowledged": false,
      "event": "workspace_storage_file_added",
      "category": "workspace",
      "sub_category": "storage",
      "object_id": "node_def456ghi789",
      "calling_user": "98765432109876543210",
      "calling_user_name": "Jane Smith",
      "org_id": "11111111111111111111",
      "workspace_id": "12345678901234567890",
      "filename": "quarterly_report.pdf",
      "file_size": 2485760
    }
  }
}

Access Rules

ConditionAccess
User is the calling_userGranted
User is the event_user (target)Granted
Event has targeted permission and user is neither target nor callerDenied
Event is internal visibilityAlways denied
User has appropriate profile-level permissionsGranted based on permission level

Error Responses

Error CodeHTTP StatusDescription
1605 (Invalid Input)400Event ID missing, empty, or not a valid OpaqueId
1609 (Not Found)404No event exists with the provided ID
1605 (Invalid Input)400Event has internal visibility
1605 (Invalid Input)400User lacks permission (targeted event)
1650 (Authentication Invalid)401Missing or invalid JWT token
1651 (Invalid Request Type)400Wrong HTTP method (only GET accepted)

Acknowledge Event

POST /current/event/{event_id}/ack/

Acknowledge (mark as read) an event for the current user. Idempotent.

Auth: Required (JWT). Default rate limiting.

Path Parameters

ParameterTypeRequiredDescription
{event_id} string Yes Alphanumeric OpaqueId of the event to acknowledge

Example Request

curl -X POST "https://api.fast.io/current/event/evt_abc123xyz789/ack/" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes"
}

Error Responses

Error CodeHTTP StatusDescription
1605 (Invalid Input)400Event ID missing or invalid
1609 (Not Found)404Event not found
1605 (Invalid Input)400Event has internal visibility
1605 (Invalid Input)400User lacks permission (targeted event)
1664 (Datastore Error)500Failed to persist the acknowledgment
1650 (Authentication Invalid)401Missing or invalid JWT token

Note: Acknowledgment is per-user. Acknowledging for one user does not affect others. Same access rules as event details apply.

Compact Responses (output=)

Every endpoint that returns event objects (search, details) accepts an optional output query parameter that selects the response shape. A single detail-level token may be combined with modifier tokens; specifying two detail levels (e.g. ?output=terse,standard) returns HTTP 400. When output= is omitted, responses are full and byte-for-byte unchanged.

LevelFields returned on each event (cumulative)
terseevent_id, event, category, object_id, created
standardterse + sub_category, calling_user, org_id, workspace_id, user_id, share_id, acknowledged, template (containing description + params), severity, visibility, notification
fullstandard + required_params, requires_parent_node, permission

Use terse for activity feed tickers and unread-count polling — it carries the event identity (event_id), name (event), category, target object, and a timestamp (created), which is the minimum a feed row needs to render without a follow-up fetch. Use standard for the most common event list/detail views — it adds subcategory, every profile-link id (calling user, owning org/workspace/share), the acknowledgment flag, the template object (which carries the human-readable description and any template params), and the render-hint enums: severity (drives feed-row color/icon), visibility (distinguishes the Activity, Audit-Log, and internal tabs), and notification (drives bell/notification rendering). Use full (or omit the parameter) for audit-log exports and event schema introspection. Unknown tokens are silently ignored. Add the markdown modifier (e.g. ?output=standard,markdown) to receive the response as GitHub-flavored Markdown (Content-Type: text/markdown; charset=UTF-8) instead of JSON — see the cross-cutting ?output= reference for the full contract.

Event Categories

CategoryAPI ValueDescription
UploaduploadFile upload operations
UseruserUser account events
OrganizationorgOrganization events
WorkspaceworkspaceWorkspace operations
ShareshareShare operations
AIaiAI/ML operations
InvitationinvitationInvitation events
EmailemailEmail-related events
BillingbillingBilling and subscription events
MetadatametadataMetadata operations
DomaindomainCustom domain events
AppsappsApplication/integration events
WorkflowworkflowWorkflow events (task lists, tasks, worklogs, approvals, todos)

Event Subcategories

SubcategoryAPI ValueDescription
StoragestorageFile and folder operations
CommentscommentsComment activity
MembersmembersMembership changes
LifecyclelifecycleCreate, update, delete, archive events
SettingssettingsConfiguration changes
SecuritysecuritySecurity-related events
AuthenticationauthenticationLogin and auth events
AIaiAI processing events
InvitationsinvitationsInvitation management
BillingbillingSubscription and payment
AssetsassetsAsset (avatar, branding) updates
UploaduploadUpload events
TransfertransferOwnership transfer events
Import/Exportimport_exportImport/export operations
Quick SharequickshareQuick share events
MetadatametadataMetadata operations
WorkflowworkflowWorkflow events

Event Visibility Levels

VisibilityAPI ValueDescription
InternalinternalSystem events. Never accessible via API.
Audit Logexternal_audit_logAudit/compliance events. Targeted permission checks bypassed for admins.
ExternalexternalStandard user-facing events.

Default (no visibility parameter): returns both external_audit_log and external events, excludes internal.

Event Permission Levels

PermissionDescription
memberAny member of the profile can view
adminOnly admins of the profile can view
targetedOnly the target user or the calling user can view

When querying with visibility=external_audit_log, targeted permission checks are bypassed.

Event Names Reference

Workspace Storage

Share Storage

Comments

Membership

Workspace Lifecycle

Share Lifecycle

AI

Metadata

Quick Shares

Invitations

User

Organization

Billing

Workflow

Event Search Examples

Recent comments in a workspace

GET /current/events/search/?workspace_id={id}&subcategory=comments

File uploads to a share in a date range

GET /current/events/search/?share_id={id}&event=share_storage_file_added&created-min=2025-12-01T06:00:00Z

Membership changes in 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

Unacknowledged events for a user

GET /current/events/search/?user_id={id}&acknowledged=false

Audit log events only

GET /current/events/search/?workspace_id={id}&visibility=external_audit_log&limit=100

Child events of a batch operation

GET /current/events/search/?parent_event_id=evt_abc123xyz789&limit=100

Workflow activity in a workspace

GET /current/events/search/?workspace_id={id}&category=workflow

Activity Polling

Long-poll endpoints for efficient change detection. The server holds the connection open and returns immediately when something changes, avoiding expensive resource polling.

Poll User Activity

GET /current/activity/poll/

Poll for activity updates on the current user's profile.

Auth: Required (JWT). Rate limited: 200 per 60s, 1000 per hour. No credit consumption.

Query Parameters

ParameterTypeRequiredDefaultDescription
wait integer No 0 Long-poll timeout in seconds (0–95). Server holds connection open until update or timeout.
lastactivity string No Current time Only return activity newer than this timestamp. Micro-precision datetime (e.g., 2025-01-20 10:30:45.123456).
updated any No If present, only return activity fields updated since lastactivity
fields string No All fields Comma-delimited activity field names to check. Max 30 fields. Supports ID qualifier via colon (e.g., storage:12345).

Example Request

curl -X GET "https://api.fast.io/current/activity/poll/?wait=30&lastactivity=2025-01-20%2010:30:45.123456" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK — activity found)

{
  "result": "yes",
  "response": {
    "results": 3,
    "activity": {
      "storage": "2025-01-20 10:30:45.123456 UTC",
      "members": "2025-01-20 09:15:22.654321 UTC",
      "settings": "2025-01-19 14:00:00.000000 UTC"
    },
    "lastactivity": "2025-01-20 10:30:45.123456 UTC"
  }
}

Response (200 OK — no activity)

{
  "result": "yes",
  "response": {
    "results": 0,
    "activity": []
  }
}

Response Fields

FieldTypeDescription
resultstring"yes" on success
response.resultsintegerNumber of activity fields returned
response.activityobjectMap of activity field names to micro-precision UTC timestamps
response.lastactivitystringMost recent timestamp; pass as lastactivity in next poll

Error Responses

Error CodeHTTP StatusDescription
1605 (Invalid Input)400Invalid profile ID format
1605 (Invalid Input)400User lacks permissions for the specified profile
1605 (Invalid Input)400Invalid field names or more than 30 fields
1665 (Object Init Failed)500Failed to initialize internal status object
1650 (Authentication Invalid)401Missing or invalid JWT token

Poll Profile Activity

GET /current/activity/poll/{profile_id}/

Poll for activity updates on a specific workspace, share, or org.

Auth: Required (JWT). Same rate limits and parameters as Poll User Activity.

Path Parameters

ParameterTypeRequiredDescription
{profile_id} string Yes 19-digit numeric profile ID (org, workspace, or share). For upload progress, use your user ID.

Access Requirements

Profile TypePermission Required
User (self)Authenticated
OrganizationPERM_VIEW on the org
WorkspacePERM_VIEW on the workspace
ShareShare view permissions + multiplayer enabled

Example Request

curl -X GET "https://api.fast.io/current/activity/poll/12345678901234567890/?wait=30&fields=storage,members&updated=1&lastactivity=2025-01-20%2010:30:45.123456" \
  -H "Authorization: Bearer {jwt_token}"

Response format is identical to Poll User Activity.


Polling Workflow

  1. Make initial poll request (no lastactivity parameter)
  2. Receive response with activity fields and lastactivity timestamp
  3. Process changes by fetching updated resources based on activity field names
  4. Make next poll with lastactivity from previous response
  5. Repeat — server returns immediately on change, or after wait seconds timeout

Activity Key Patterns

Key PatternWhat Changed
storage:{fileId}File added, updated, or removed
preview:{fileId}File preview/thumbnail is ready
metadata:{fileId}File's extracted metadata fields were written (use to refresh a single row during a template extraction)
ai_chat:{chatId}AI chat message updated
comments:{nodeId}Comment added or updated
member:{userId}Membership changed

Anti-Patterns

WebSocket (Real-Time)

Optional real-time delivery (~300ms latency vs ~1s for polling). Sends both activity messages (field names for change detection) and enriched event messages (full event details) via WebSocket. Backwards compatible — existing clients continue to work without changes.

WebSocket Auth

GET /current/websocket/auth/{profile_id}

Generate a WebSocket authentication JWT for a specific profile. Tokens are valid for 24 hours.

Auth: Required (JWT). No credit consumption.

Path Parameters

ParameterTypeRequiredDescription
{profile_id} string Yes 19-digit numeric ID of the user, org, workspace, or share to subscribe to

Example Request

curl -X GET "https://api.fast.io/current/websocket/auth/12345678901234567890" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "expires_in": 86400,
    "auth_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
resultstring"yes" on success
response.expires_inintegerToken lifetime in seconds (86400 = 24 hours)
response.auth_tokenstringSigned JWT with websocket scope, bound to the requested profile

Access Requirements

Profile TypePermission Required
User (self)None beyond authentication
OrganizationPERM_VIEW on the org
WorkspacePERM_VIEW on the workspace
SharecanViewShareDetails

Error Responses

Error CodeHTTP StatusDescription
1605 (Invalid Input)400No profile ID provided or invalid format
1605 (Invalid Input)400Profile type unsupported, not found, or user lacks permissions
1650 (Authentication Invalid)401Missing or invalid JWT, or internal JWT generation failure

WebSocket Connection

Connect to: wss://{host}/api/websocket/?token={auth_token}

Where {auth_token} is the JWT returned from the auth endpoint above.

Message Types

The server pushes two types of JSON messages:

activity Messages

Indicate which resource categories changed. Use these to know what to re-fetch:

{
  "response": "activity",
  "activity": ["storage:2abc...", "preview:2abc..."]
}

The activity array contains the same activity key patterns as the polling endpoint.

event Messages

Sent alongside activity messages when structured event data is available. Provide full event details for immediate UI updates without a follow-up API call:

{
  "result": true,
  "response": "event",
  "time": "2026-03-22 14:30:45.123456 UTC",
  "timestamp": "1711123456.1234",
  "event": "workspace_storage_file_added",
  "category": "workspace",
  "sub_category": "storage",
  "object_id": "abc123def456ghi789jkl012mno345",
  "calling_user": "12345678901234567890",
  "activity_field": "storage",
  "data": {
    "name": "report.pdf",
    "parent_node_id": "xyz789...",
    "size": 1048576
  }
}
event Message Fields
FieldTypeDescription
resultbooleanAlways true for event messages
responsestringAlways "event" for this message type
timestringServer send time in MySQL datetime format with microseconds (e.g., "2026-03-22 14:30:45.123456 UTC"). Added by the WebSocket server when the message is dispatched.
timestampstringEvent trigger time as a microtime float string (e.g., "1711123456.1234"). Set when the event is created by the Activity system.
eventstringEvent name identifier (e.g., workspace_storage_file_added)
categorystringEvent category (e.g., workspace, share)
sub_categorystringEvent subcategory (e.g., storage, members)
object_idstringAffected object OpaqueId (file, folder, etc.)
calling_userstring19-digit numeric ID of the user who triggered the event
activity_fieldstringCorresponding activity field name (e.g., storage)
dataobjectEvent-specific details; shape varies by event type
Backwards Compatibility

activity messages are always sent. event messages are supplementary — sent alongside activity messages when structured event data is available. Existing clients need no changes. Event payloads are kept under ~4KB.

Permission gating: Enriched event messages are only sent for member-level events. Admin and targeted events receive only the activity message.

Fallback

If the WebSocket connection drops, fall back to long-polling (GET /current/activity/poll/{profile_id}/). Activity polling returns field names and timestamps. To retrieve full event details after reconnection, use GET /current/events/search/ with a created-min filter.

Realtime Auth (Collaborative Rooms)

Separate from WebSocket activity channels, these endpoints provide authentication for collaborative editing rooms.

Generate Realtime Token

GET /current/realtime/auth/{room_id}

Generate a realtime JWT for a workspace or share collaborative room. Tokens are valid for 24 hours.

Auth: Required (JWT). Not rate limited. No credit consumption.

Path Parameters

ParameterTypeRequiredDescription
{room_id} string Yes 19-digit numeric ID of the workspace or share to join

Example Request

curl -X GET "https://api.fast.io/current/realtime/auth/12345678901234567890" \
  -H "Authorization: Bearer {jwt_token}"

Response (200 OK)

{
  "result": "yes",
  "response": {
    "expires_in": 86400,
    "auth_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "current_api_version": "1.0"
}

Access Requirements

Profile TypePermission Required
WorkspaceAt least PERM_VIEW
SharecanViewShareDetails + multiplayer enabled

Error Responses

Error CodeHTTP StatusDescription
1605 (Invalid Input)400Missing room ID
1605 (Invalid Input)400Room ID is not numeric
1605 (Invalid Input)400Room ID does not correspond to a workspace or share
1680 (Access Denied)403User lacks permissions on the room
1650 (Authentication Invalid)401Missing or invalid JWT, or internal JWT generation failure

Note: Only workspace and share profile types are accepted as room IDs.


Validate Realtime Token

GET /current/realtime/auth/validate/

Validate a realtime JWT and extract the room ID. Intended for backend services to verify tokens.

Auth: Bearer token in Authorization header (the realtime JWT to validate, not a user JWT).

Example Request

curl -X GET "https://api.fast.io/current/realtime/auth/validate/" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response (200 OK)

{
  "result": "yes",
  "response": {
    "room_id": "12345678901234567890"
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
resultstring"yes" on success
response.room_idstringThe workspace or share profile ID the token is bound to

Error Responses

Error CodeHTTP StatusDescription
1650 (Authentication Invalid)401Missing Authorization header
1605 (Invalid Input)400Malformed Authorization header
1605 (Invalid Input)400Authorization header does not use Bearer scheme
1605 (Invalid Input)400Bearer keyword present but no token follows
1605 (Invalid Input)400Token is not valid JWT format
1680 (Access Denied)403Token signature verification or expiration check failed
1654 (Internal Error)500Token payload is malformed or missing required fields
1605 (Invalid Input)400Token scope is not realtime

Notes: Only validates tokens with realtime scope. WebSocket-scoped tokens are rejected. Validation is performed using the JWT alone.

↑ Back to top