Persistent bidirectional connection for real-time updates, live events, and request/response messaging.
WebSocket API
The WebSocket API provides a persistent connection for receiving real-time events and sending actions. It is the primary data interface used by the TRCR web application and supports all operations available via REST.
Endpoint:wss://api.trcr.pro/ws
Connection Flow
WebSocket authentication uses a ticket-based system. First obtain a short-lived ticket via REST, then present it when connecting.
Step 1: Get a WebSocket Ticket
POST https://api.trcr.pro/api/v1/auth/ws-ticket
Authorization: Bearer YOUR_ACCESS_TOKEN
Response:
{ "ticket": "wst_a1b2c3d4e5f6..." }
Tickets expire after 30 seconds and can only be used once.
Step 2: Connect and Authenticate
Open a WebSocket connection and immediately send an authentication message:
Create multiple tasks in one call (each item accepts start_date)
tasks.update
{ id, start_date?, due_date?, ...fields }
Update a task (start_date accepted; must be on or before due_date)
tasks.update_status
{ id, status }
Update task status; triggers email and in-app notifications for reporter and assignees
tasks.delete
{ id }
Delete a task
tasks.reorder
{ task_id, position, group_id? }
Reorder a task within its group
tasks.add_comment
{ task_id, body }
Add a comment
tasks.delete_comment
{ task_id, comment_id }
Delete a comment
tasks.checklist.list
{ task_id }
List checklist items for a task
tasks.checklist.create
{ task_id, title }
Add a checklist item (requires manage_tasks)
tasks.checklist.toggle
{ item_id }
Toggle checklist item completed state (any org member)
tasks.checklist.delete
{ item_id }
Delete a checklist item (requires manage_tasks)
tasks.dependency.list
{ task_id }
List task dependencies (blocked_by / blocks)
tasks.dependency.add
{ task_id, depends_on_id, dependency_type }
Add a dependency link; dependency_type is blocks or blocked_by (requires manage_tasks)
tasks.dependency.remove
{ task_id, dependency_id }
Remove a dependency link (requires manage_tasks)
tasks.dependencies.list_all
{ org_id }
List every task dependency in the organization in one call (returns only edges where both endpoint tasks are visible to the caller)
Projects
Action
Payload
Description
projects.list
{ status?, search? }
List projects
projects.get
{ id }
Get a project
projects.create
{ name, ... }
Create a project
projects.update
{ id, ...fields }
Update a project
projects.delete
{ id }
Delete a project
Task Groups
Action
Payload
Description
task_groups.list
{ project_id }
List task groups for a project
task_groups.create
{ project_id, name }
Create a task group
task_groups.update
{ project_id, group_id, name }
Update a task group
task_groups.delete
{ project_id, group_id }
Delete a task group
task_groups.reorder
{ project_id, order }
Reorder task groups (order is array of group IDs)
task_groups.toggle_collapsed
{ project_id, group_id }
Toggle collapsed state for the current user
Task Statuses
Action
Payload
Description
task_statuses.list
{}
List custom task statuses
task_statuses.create
{ code, label, color, ... }
Create a custom status
task_statuses.update
{ id, ...fields }
Update a custom status
task_statuses.delete
{ id }
Delete a custom status
Task Recurrences
Action
Payload
Description
task_recurrences.create
{ task_id, recurrence_pattern }
Set a task to repeat (daily, weekly, monthly, or cron)
task_recurrences.get
{ recurrence_id }
Get a recurrence rule
task_recurrences.update
{ recurrence_id, recurrence_pattern }
Update a recurrence rule
task_recurrences.delete
{ recurrence_id }
Stop a recurrence
Organizations
Action
Payload
Description
organizations.list
{}
List user's organizations
organizations.get
{ id }
Get an organization
organizations.create
{ name, slug? }
Create an organization
organizations.update
{ id, ...fields }
Update an organization
organizations.delete
{ id }
Delete an organization
Members
Action
Payload
Description
members.list
{ role? }
List organization members
members.invite
{ email, role? }
Invite a member
members.update
{ user_id, role }
Update a member's role
members.remove
{ user_id }
Remove a member
User Profile
Action
Payload
Description
users.me
{}
Get the authenticated user's profile (id, email, full_name, avatar_url, email_verified, timezone, locale)
users.update_profile
{ full_name?, timezone?, locale? }
Update the profile; omitted fields are unchanged. locale is a BCP-47 code (en, es, fr, pt, de, uk, it, pl, nl, ja); send "" to clear it back to null (browser detection), any other value returns a validation error. Returns the updated user and emits EntityChanged for cross-device sync.
users.update_avatar
{ avatar_url }
Set the avatar from a URL
users.remove_avatar
{}
Remove the avatar
users.change_password
{ current_password, new_password }
Change the account password
Push Tokens
Action
Payload
Description
users.register_push_token
{ token, device_type? }
Register (idempotent upsert) a device push token. device_type is ios, android, or web (default ios). Returns the token record.
users.delete_push_token
{ id }
Remove one of the caller's own push tokens (e.g. on logout)
Update a milestone; send description: null to clear it, omit a field to leave it unchanged (requires manage_tasks)
milestones.delete
{ org_id, milestone_id }
Delete a milestone (requires manage_tasks)
Sidebar
Action
Payload
Description
sidebar.get_collapsed
{}
Get collapsed sidebar node IDs
sidebar.toggle_collapsed
{ project_id }
Toggle a sidebar node collapsed state
Dashboard
Action
Payload
Description
dashboard.summary
{}
Get dashboard summary (total tasks, done, overdue)
Audit
Action
Payload
Description
audit.list
{ user_id?, action?, entity_type?, from?, to? }
List audit log entries (admin only)
Heartbeat / Keep-Alive
The server sends a ping frame every 30 seconds. If your WebSocket library does not automatically respond with a pong, you must handle it manually. If no pong is received within 10 seconds, the server closes the connection.
You can also send a ping action to test the connection: