Events & Activity Event search, activity polling, WebSocket realtime, and webhooks.
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.
Events Search
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
/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 (shared channel events_search).
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| 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 (20-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 (ISO 8601, e.g., 2025-12-01T06:00:00Z) |
| created-max | string | No | — | Upper bound for event creation time (ISO 8601; 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 |
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",
"subcategory": "storage",
"object_id": "node_def456ghi789",
"calling_user_id": "98765432109876543210",
"calling_user_name": "Jane Smith",
"org_id": "11111111111111111111",
"workspace_id": "12345678901234567890",
"filename": "quarterly_report.pdf",
"file_size": 2485760
}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| result | string | "yes" on success |
| response.events | array | Array of event objects |
| response.events[].event_id | string | Unique event identifier (alphanumeric OpaqueId) |
| response.events[].created | string | Event timestamp in Y-m-d H:i:s format |
| response.events[].acknowledged | boolean | Whether the current user has acknowledged this event |
| response.events[].event | string | Event name identifier (e.g., workspace_storage_file_added) |
| response.events[].category | string | Event category name |
| response.events[].subcategory | string | Event subcategory name |
| response.events[].object_id | string | Related object OpaqueId (if applicable) |
| response.events[].calling_user_id | string | 20-digit numeric ID of the triggering user |
| response.events[].calling_user_name | string | Display name of the triggering user |
| response.events[].org_id | string | Organization ID context (if applicable) |
| response.events[].workspace_id | string | Workspace ID context (if applicable) |
| response.events[].share_id | string | Share ID context (if applicable) |
| response.events[].user_id | string | Target 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 Code | HTTP Status | Description |
|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | No profile filter or parent_event_id provided |
APP_ERROR_INPUT_INVALID | 400 | created-min is greater than created-max |
APP_ERROR_INPUT_INVALID | 400 | parent_event_id combined with disallowed filters |
APP_DENIED | 403 | Token scope does not include the requested profile |
APP_ERROR_QUERY_ERROR | 500 | Internal database error during event search |
APP_AUTH_INVALID | 401 | Missing or invalid JWT token |
APP_REQUEST_TYPE | 400 | Wrong HTTP method (only GET accepted) |
Notes: Results are cached for 10 seconds with automatic invalidation when new events are committed. OAuth scoped tokens enforce entity-level access: events are filtered to only entities within the token's scope. Post-query permission filtering silently excludes events the user cannot access.
Summarize Events (AI)
/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 events_search rate limit channel.
Additional Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| 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)
| Field | Type | Description |
|---|---|---|
| response.summary | object|null | AI-generated summary, or null if no events or generation failed |
| response.summary.text | string | Natural language summary with @[type:ID:name] mention pills |
| response.summary.metrics.total_events | integer | Total events summarized |
| response.summary.metrics.unique_actors | integer | Distinct users who triggered events |
| response.summary.metrics.date_range.start | string | ISO 8601 timestamp of earliest event |
| response.summary.metrics.date_range.end | string | ISO 8601 timestamp of most recent event |
| response.summary.metrics.categories | object | Map of category names to event counts |
Summary Mention Pill Formats
| Entity | Format | Example |
|---|---|---|
| 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:
summaryisnullbut events are still returned. Requires a billable organization for AI token billing (resolved from profile context).
Event Details
/current/event/{event_id}/details/
Get full details for a single event.
Auth: Required (JWT). Default rate limiting. Credit limit checks are skipped.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| {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",
"subcategory": "storage",
"object_id": "node_def456ghi789",
"calling_user_id": "98765432109876543210",
"calling_user_name": "Jane Smith",
"org_id": "11111111111111111111",
"workspace_id": "12345678901234567890",
"filename": "quarterly_report.pdf",
"file_size": 2485760
}
}
}
Access Rules
| Condition | Access |
|---|---|
User is the calling_user | Granted |
User is the event_user (target) | Granted |
Event has targeted permission and user is neither target nor caller | Denied |
Event is internal visibility | Always denied |
| User has appropriate profile-level permissions | Granted based on permission level |
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | Event ID missing, empty, or not a valid OpaqueId |
APP_ERROR_NOT_FOUND | 404 | No event exists with the provided ID |
APP_ERROR_INPUT_INVALID | 400 | Event has internal visibility |
APP_ERROR_INPUT_INVALID | 400 | User lacks permission (targeted event) |
APP_AUTH_INVALID | 401 | Missing or invalid JWT token |
APP_REQUEST_TYPE | 400 | Wrong HTTP method (only GET accepted) |
Acknowledge Event
/current/event/{event_id}/ack/
Acknowledge (mark as read) an event for the current user. Idempotent.
Auth: Required (JWT). Default rate limiting.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| {event_id} | string | Yes | Alphanumeric OpaqueId of the event to acknowledge |
Example Request
curl -X GET "https://api.fast.io/current/event/evt_abc123xyz789/ack/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | Event ID missing or invalid |
APP_ERROR_NOT_FOUND | 404 | Event not found |
APP_ERROR_INPUT_INVALID | 400 | Event has internal visibility |
APP_ERROR_INPUT_INVALID | 400 | User lacks permission (targeted event) |
APP_ERROR_DATASTORE | 500 | Failed to persist the acknowledgment |
APP_AUTH_INVALID | 401 | Missing or invalid JWT token |
Note: Acknowledgment is per-user. Acknowledging for one user does not affect others. Same access rules as event details apply.
Event Categories
| Category | API Value | Description |
|---|---|---|
| Upload | upload | File upload operations |
| User | user | User account events |
| Organization | org | Organization events |
| Workspace | workspace | Workspace operations |
| Share | share | Share operations |
| AI | ai | AI/ML operations |
| Invitation | invitation | Invitation events |
email | Email-related events | |
| Billing | billing | Billing and subscription events |
| Metadata | metadata | Metadata operations |
| Domain | domain | Custom domain events |
| Apps | apps | Application/integration events |
| Workflow | workflow | Workflow events (task lists, tasks, worklogs, approvals, todos) |
Event Subcategories
| Subcategory | API Value | Description |
|---|---|---|
| Storage | storage | File and folder operations |
| Comments | comments | Comment activity |
| Members | members | Membership changes |
| Lifecycle | lifecycle | Create, update, delete, archive events |
| Settings | settings | Configuration changes |
| Security | security | Security-related events |
| Authentication | authentication | Login and auth events |
| AI | ai | AI processing events |
| Invitations | invitations | Invitation management |
| Billing | billing | Subscription and payment |
| Assets | assets | Asset (avatar, branding) updates |
| Upload | upload | Upload events |
| Transfer | transfer | Ownership transfer events |
| Import/Export | import_export | Import/export operations |
| Quick Share | quickshare | Quick share events |
| Metadata | metadata | Metadata operations |
| Workflow | workflow | Workflow events |
Event Visibility Levels
| Visibility | API Value | Description |
|---|---|---|
| Internal | internal | System events. Never accessible via API. |
| Audit Log | external_audit_log | Audit/compliance events. Targeted permission checks bypassed for admins. |
| External | external | Standard user-facing events. |
Default (no visibility parameter): returns both external_audit_log and external events, excludes internal.
Event Permission Levels
| Permission | Description |
|---|---|
member | Any member of the profile can view |
admin | Only admins of the profile can view |
targeted | Only 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
workspace_storage_file_added— File uploadedworkspace_storage_file_deleted— File trashedworkspace_storage_file_moved— File movedworkspace_storage_file_copied— File copiedworkspace_storage_file_updated— File metadata updatedworkspace_storage_file_restored— File restored from trashworkspace_storage_file_version_restored— File version restoredworkspace_storage_folder_created— Folder createdworkspace_storage_folder_deleted— Folder trashedworkspace_storage_folder_moved— Folder movedworkspace_storage_download_token_created— Download token issuedworkspace_storage_zip_downloaded— ZIP download completedworkspace_storage_link_added— Link added
Share Storage
share_storage_file_added— File uploadedshare_storage_file_deleted— File trashedshare_storage_file_moved— File movedshare_storage_file_copied— File copiedshare_storage_file_updated— File metadata updatedshare_storage_file_restored— File restoredshare_storage_folder_created— Folder createdshare_storage_folder_deleted— Folder trashedshare_storage_folder_moved— Folder movedshare_storage_download_token_created— Download token issuedshare_storage_zip_downloaded— ZIP download completed
Comments
comment_created— Comment createdcomment_updated— Comment updatedcomment_deleted— Comment deletedcomment_mentioned— User mentioned in comment (targeted permission)comment_replied— Reply to a commentcomment_reaction— Reaction added
Membership
added_member_to_org/removed_member_from_org— Org membershipadded_member_to_workspace/removed_member_from_workspace— Workspace membershipadded_member_to_share/removed_member_from_share— Share membershipmembership_updated— Permission changes
Workspace Lifecycle
workspace_created/workspace_updated/workspace_deletedworkspace_archived/workspace_unarchived
Share Lifecycle
share_created/share_updated/share_deletedshare_archived/share_unarchivedshare_imported_to_workspace— Share imported into workspace
AI
ai_chat_created/ai_chat_updated/ai_chat_deleted— Chat lifecycleai_chat_new_message— New AI chat messageai_chat_published— Chat publishednode_ai_summary_created— AI summary generated for a fileworkspace_ai_share_created— AI share created in workspace
Metadata
metadata_kv_update/metadata_kv_delete/metadata_kv_extractmetadata_template_update/metadata_template_delete/metadata_template_selectmetadata_view_update/metadata_view_delete
Quick Shares
workspace_quickshare_created/workspace_quickshare_updated/workspace_quickshare_deletedworkspace_quickshare_file_downloaded/workspace_quickshare_file_previewed
Invitations
invitation_email_sent/invitation_accepted/invitation_declined
User
user_created/user_updated/user_deleteduser_email_reset/user_asset_updated
Organization
org_created/org_updated/org_closedorg_transfer_token_created/org_transfer_completed
Billing
subscription_created/subscription_cancelledbilling_free_trial_ended
Workflow
task_list_created/task_list_updated/task_list_deletedtask_created/task_updated/task_deletedtask_status_changed/task_assigned/task_completedworklog_entry_createdworklog_interjection_created/worklog_interjection_acknowledgedapproval_requested/approval_approved/approval_rejectedtodo_created/todo_toggled/todo_deleted/todo_updated
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
/current/activity/poll/
Poll for activity updates on the current user's profile.
Auth: Required (JWT). Rate limited: 200 per 60s, 1000 per hour. Credit limit checks skipped.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| 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
| Field | Type | Description |
|---|---|---|
| result | string | "yes" on success |
| response.results | integer | Number of activity fields returned |
| response.activity | object | Map of activity field names to micro-precision UTC timestamps |
| response.lastactivity | string | Most recent timestamp; pass as lastactivity in next poll |
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | Invalid profile ID format |
APP_ERROR_INPUT_INVALID | 400 | User lacks permissions for the specified profile |
APP_ERROR_INPUT_INVALID | 400 | Invalid field names or more than 30 fields |
APP_ERROR_OBJECT_INIT | 500 | Failed to initialize internal status object |
APP_AUTH_INVALID | 401 | Missing or invalid JWT token |
Poll Profile Activity
/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
| Parameter | Type | Required | Description |
|---|---|---|---|
| {profile_id} | string | Yes | 20-digit numeric profile ID (org, workspace, or share). For upload progress, use your user ID. |
Access Requirements
| Profile Type | Permission Required |
|---|---|
| User (self) | Authenticated |
| Organization | PERM_VIEW on the org |
| Workspace | PERM_VIEW on the workspace |
| Share | Share 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
- Make initial poll request (no
lastactivityparameter) - Receive response with
activityfields andlastactivitytimestamp - Process changes by fetching updated resources based on activity field names
- Make next poll with
lastactivityfrom previous response - Repeat — server returns immediately on change, or after
waitseconds timeout
Activity Key Patterns
| Key Pattern | What Changed |
|---|---|
storage:{fileId} | File added, updated, or removed |
preview:{fileId} | File preview/thumbnail is ready |
ai_chat:{chatId} | AI chat message updated |
comments:{nodeId} | Comment added or updated |
member:{userId} | Membership changed |
Anti-Patterns
- Do NOT loop on resource detail endpoints to wait for previews or processing.
- Instead, poll on the workspace/share and watch for the relevant activity key.
- For uploads, use your user ID as the
profile_idsince upload progress is tied to the user, not a workspace.
WebSocket (Real-Time)
Optional real-time delivery (~300ms latency vs ~1s for polling). Provides the same data as activity polling but pushed immediately via WebSocket.
WebSocket Auth
/current/websocket/auth/{profile_id}
Generate a WebSocket authentication JWT for a specific profile. Tokens are valid for 24 hours.
Auth: Required (JWT). Credit limit checks skipped.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| {profile_id} | string | Yes | 20-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
| Field | Type | Description |
|---|---|---|
| result | string | "yes" on success |
| response.expires_in | integer | Token lifetime in seconds (86400 = 24 hours) |
| response.auth_token | string | Signed JWT with websocket scope, bound to the requested profile |
Access Requirements
| Profile Type | Permission Required |
|---|---|
| User (self) | None beyond authentication |
| Organization | PERM_VIEW on the org |
| Workspace | PERM_VIEW on the workspace |
| Share | canViewShareDetails |
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | No profile ID provided or invalid format |
APP_ERROR_INPUT_INVALID | 400 | Profile type unsupported, not found, or user lacks permissions |
APP_AUTH_INVALID | 401 | Missing 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 Format
The server pushes JSON messages when resources change:
{
"response": "activity",
"activity": ["storage:2abc...", "preview:2abc..."]
}
The activity array contains the same activity key patterns as the polling endpoint. Fetch only the resources that have changed.
Fallback
If the WebSocket connection drops, fall back to long-polling (GET /current/activity/poll/{profile_id}/). The data is identical, with slightly higher latency (~1s vs ~300ms).
Realtime Auth (Collaborative Rooms)
Separate from WebSocket activity channels, these endpoints provide authentication for YJS-based collaborative editing rooms.
Generate Realtime Token
/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. Credit limit checks skipped.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| {room_id} | string | Yes | 20-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 Type | Permission Required |
|---|---|
| Workspace | At least PERM_VIEW |
| Share | canViewShareDetails + multiplayer enabled |
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | Missing room ID |
APP_ERROR_INPUT_INVALID | 400 | Room ID is not numeric |
APP_ERROR_INPUT_INVALID | 400 | Room ID does not correspond to a workspace or share |
APP_DENIED | 403 | User lacks permissions on the room |
APP_AUTH_INVALID | 401 | Missing or invalid JWT, or internal JWT generation failure |
Note: Only workspace and share profile types are accepted as room IDs.
Validate Realtime Token
/current/realtime/auth/validate/
Validate a realtime JWT and extract the room ID. Intended for server-side components 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
| Field | Type | Description |
|---|---|---|
| result | string | "yes" on success |
| response.room_id | string | The workspace or share profile ID the token is bound to |
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_AUTH_INVALID | 401 | Missing Authorization header |
APP_ERROR_INPUT_INVALID | 400 | Malformed Authorization header |
APP_ERROR_INPUT_INVALID | 400 | Authorization header does not use Bearer scheme |
APP_ERROR_INPUT_INVALID | 400 | Bearer keyword present but no token follows |
APP_ERROR_INPUT_INVALID | 400 | Token is not valid JWT format |
APP_DENIED | 403 | Token signature verification or expiration check failed |
APP_ERROR_GENERAL | 500 | Token payload is malformed or missing required fields |
APP_ERROR_INPUT_INVALID | 400 | Token scope is not realtime |
Notes: Only validates tokens with
realtimescope. WebSocket-scoped tokens are rejected. No user session or database lookup is performed beyond JWT verification.
Webhooks
Inbound webhook endpoints that receive event notifications from third-party services. These endpoints are not called by API consumers.
Stripe Billing Webhook
/current/webhooks/billing/stripe/
Receive and queue a Stripe billing webhook event. Called by Stripe, not by API consumers.
Auth: Stripe HMAC-SHA256 signature verification via Stripe-Signature header (not Bearer token).
Request Headers
| Header | Required | Description |
|---|---|---|
Stripe-Signature | Yes | Stripe signature: t={timestamp},v1={signature} |
Content-Type | Yes | application/json |
Request Body: Raw JSON event object from Stripe.
Example Request
curl -X POST "https://api.fast.io/current/webhooks/billing/stripe/" \
-H "Content-Type: application/json" \
-H "Stripe-Signature: t=1492774577,v1=5257a869..." \
-d '{"id":"evt_test","object":"event","type":"invoice.paid","data":{"object":{}}}'
Response (202 Accepted)
{
"result": "yes",
"current_api_version": "1.0"
}
Error Responses
| Error Code | HTTP Status | Description |
|---|---|---|
APP_REQUEST_TYPE | 400 | Request method is not POST |
APP_ERROR_INPUT_INVALID | 400 | Stripe-Signature header missing, malformed, or cannot be parsed |
APP_ERROR_INPUT_INVALID | 400 | HMAC verification failed (timestamp out of range or hash mismatch) |
APP_ERROR_INPUT_INVALID | 400 | Request body is not valid JSON |
APP_ENQUEUE_FAILED | 500 | Event valid but could not be placed on processing queue |
↑ Back to topNotes: Only POST requests are accepted. Signature verification enforces a 5-minute tolerance window for timestamp drift. Events are queued for asynchronous processing; the response confirms receipt, not processing. Stripe retries failed deliveries (non-2xx responses).