Authentication
All API requests (except register and login) require a JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
Register
| Method | Endpoint | Auth |
| POST | /api/register | None |
Request Body
usernamestring2-32 characters, unique
passwordstringMinimum 6 characters
Example
POST /api/register
Content-Type: application/json
{
"username": "alice",
"password": "mypassword123"
}
Response (201)
{
"token": "eyJhbGci...",
"userId": "a1b2c3d4...",
"username": "alice"
}
Login
| Method | Endpoint | Auth |
| POST | /api/login | None |
Request Body
usernamestringRegistered username
passwordstringAccount password
Response (200)
{
"token": "eyJhbGci...",
"userId": "a1b2c3d4...",
"username": "alice"
}
Application Management
Each application gets a unique appId that isolates WebSocket connections. Users only see cursors from the same appId.
Create Application
| Method | Endpoint | Auth |
| POST | /api/apps | Bearer Token |
namestringApplication display name
allowedOriginsstringComma-separated origins, or * for all (default)
Response (201)
{
"id": "internal-uuid",
"appId": "a1b2c3d4e5f6...",
"name": "My Website",
"allowedOrigins": "*",
"createdAt": "2026-01-01T00:00:00Z"
}
List Applications
| Method | Endpoint | Auth |
| GET | /api/apps | Bearer Token |
Response (200)
{
"apps": [
{
"id": "...",
"appId": "...",
"name": "My Website",
"allowedOrigins": "*",
"createdAt": "2026-01-01T00:00:00Z"
}
]
}
Delete Application
| Method | Endpoint | Auth |
| DELETE | /api/apps/:appId | Bearer Token |
Deletes an application. Only the owner can delete it.
Response (200)
{ "success": true }
WebSocket Connection
| Method | Endpoint | Auth |
| GET (Upgrade) | /ws?appId=xxx&userId=xxx&username=xxx | appId validation |
Connect via WebSocket to start syncing cursor positions. The server validates the appId before accepting the connection.
const ws = new WebSocket(
"wss://cursor.xn--kiv483g.online/ws?appId=YOUR_APP_ID&userId=user1&username=Alice"
);
Stats
| Method | Endpoint | Auth |
| GET | /api/stats/:appId | None |
Returns the current online user count and user list for the specified application. No authentication required.
Example
GET /api/stats/demo-app-00000001
Response (200)
{
"online": 3,
"users": [
{ "userId": "abc123", "username": "Alice", "color": "hsl(120,70%,50%)", "x": 320, "y": 480 },
{ "userId": "def456", "username": "Bob", "color": "hsl(240,70%,50%)", "x": 100, "y": 200 },
{ "userId": "ghi789", "username": "Carol", "color": "hsl(30,70%,50%)", "x": 0, "y": 0 }
]
}
SDK Usage
Auto-init (recommended)
<script src="https://cursor.xn--kiv483g.online/sdk/cursor-sync.js"
data-app-id="YOUR_APP_ID"
data-username="MyName"></script>
Manual init
<script src="https://cursor.xn--kiv483g.online/sdk/cursor-sync.js"></script>
<script>
CursorSync.init({
serverUrl: "https://your-server.com",
appId: "YOUR_APP_ID",
username: "MyName",
lang: "en"
});
</script>
SDK API
init(options)functionInitialize and connect
destroy()functionDisconnect and clean up
setUsername(name)functionUpdate username and reconnect
isConnected()functionReturns boolean connection state
getUserId()functionReturns current user ID
getConfig()functionReturns current configuration object
sendMessage(userId,text)functionSend a message to a user
pinUser(userId)functionPin a user's cursor
unpinUser()functionUnpin the pinned cursor
Configuration Options (data attributes or init options)
cursorSizenumberCursor diameter in px (default: 20)
borderWidthnumberCursor border width in px (default: 2)
showLabelbooleanShow username label next to cursor (default: true)
showRegionbooleanShow region under username (default: true)
enableTrailbooleanEnable cursor trail effect (default: true)
trailLengthnumberNumber of trail points 0-20 (default: 8)
trailIntervalnumberTrail render interval in ms (default: 60)
enableRipplebooleanEnable click ripple effect (default: true)
rippleDurationnumberRipple animation duration in ms (default: 800)
rippleScalenumberRipple max scale factor (default: 13)
throttleMsnumberCursor sync throttle in ms (default: 50)
heartbeatnumberHeartbeat interval in ms (default: 30000)
reconnectBasenumberBase reconnect delay in ms (default: 1000)
bubbleDurationnumberSpeech bubble display duration in ms (default: 5000)
pinThresholdnumberClick distance to pin a cursor in px (default: 40)
Use the Settings page to generate a customized embed code with a live preview.
Message Protocol
Client to Server
// Cursor move
{ "type": "cursor", "x": 100, "y": 200 }
// Click event
{ "type": "click", "x": 100, "y": 200 }
// Send message
{ "type": "message", "text": "Hello!", "targetUserId": "xxx" }
// Heartbeat
{ "type": "ping" }
// Batch (reduce message count)
{ "type": "batch", "messages": [...] }
Server to Client
// Remote cursor
{ "type": "cursor", "userId": "xxx", "username": "Bob", "color": "hsl(...)", "x": 100, "y": 200 }
// Click ripple
{ "type": "click", "userId": "xxx", "x": 100, "y": 200, "color": "hsl(...)" }
// User join
{ "type": "join", "userId": "xxx", "username": "Bob", "color": "hsl(...)", "region": "Beijing, CN" }
// User leave
{ "type": "leave", "userId": "xxx" }
// Online users (on connect)
{ "type": "presence", "users": [...] }
// Chat message
{ "type": "message", "userId": "xxx", "username": "Bob", "color": "hsl(...)", "text": "Hello!", "targetUserId": "yyy" }
// Heartbeat reply
{ "type": "pong" }