Skip to main content

Sync Protocol Reference

Complete type reference for the Periscope WebSocket and REST sync protocol

The sync protocol defines the message format for communication between the Periscope browser extension and the Periscope service. Messages are exchanged over WebSocket for real-time sync or via the REST API for batch operations.


SyncMessage

The top-level envelope for all sync operations.

FieldTypeRequiredDescription
idstringYesUnique message identifier (UUID v4)
typeSyncOperationTypeYesThe operation being performed
timestampstringYesISO 8601 timestamp of when the message was created
userIdstringYesAuthenticated user ID
extensionIdstringYesUnique identifier of the browser extension instance
payloadSyncPayloadYesOperation-specific payload (discriminated on type)

Example

json
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "type": "navigate",
  "timestamp": "2026-03-02T14:30:00.000Z",
  "userId": "usr_abc123",
  "extensionId": "ext_def456",
  "payload": {
    "type": "navigation",
    "tabId": "tab_789",
    "url": "https://docs.uselovelace.com/periscope",
    "previousUrl": "https://docs.uselovelace.com",
    "title": "Periscope - Lovelace Developer Portal",
    "transitionType": "link",
    "navigationTime": 320
  }
}

SyncOperationType

Enum of valid operation types for SyncMessage.type.

ValueDescription
createCreate a new browser context record
updateUpdate an existing browser context
deleteDelete a browser context
activateMark a tab as the active tab
deactivateMark a tab as inactive
navigateRecord a page navigation event
heartbeatKeep-alive signal with extension status

SyncPayload Variants

The payload field is a discriminated union. The type field determines which variant applies.

ContextSyncPayload

Used with create, update, and delete operations.

FieldTypeRequiredDescription
type"context"YesDiscriminator
operation"create" | "update" | "delete"YesThe context operation
contextBrowserContextYesThe full browser context object
deltaobjectNoPartial update fields (for update operations only)

TabActivationPayload

Used with activate and deactivate operations.

FieldTypeRequiredDescription
type"tab_activation"YesDiscriminator
tabIdstringYesID of the tab being activated or deactivated
previousTabIdstringNoID of the previously active tab
windowIdstringNoBrowser window ID
urlstringNoURL of the activated tab
titlestringNoTitle of the activated tab

NavigationPayload

Used with navigate operations.

FieldTypeRequiredDescription
type"navigation"YesDiscriminator
tabIdstringYesID of the tab where navigation occurred
urlstringYesDestination URL
previousUrlstringNoURL before navigation
titlestringNoPage title of the destination
transitionTypeenumYesHow the navigation was triggered
navigationTimenumberNoNavigation duration in milliseconds

transitionType values: link, typed, auto_bookmark, auto_subframe, manual_subframe, generated, start_page, form_submit, reload, keyword, keyword_generated

HeartbeatPayload

Used with heartbeat operations. Must be sent at least every 60 seconds (recommended: 25-30 seconds).

FieldTypeRequiredDescription
type"heartbeat"YesDiscriminator
activeTabIdstringNoCurrently active tab ID
totalTabsnumberNoTotal number of open tabs
extensionVersionstringNoInstalled extension version
browserInfostringNoBrowser name and version

SyncResponse

Returned by the server for every SyncMessage.

FieldTypeRequiredDescription
messageIdstringYesID of the original SyncMessage this responds to
successbooleanYesWhether the operation succeeded
timestampstringYesISO 8601 server timestamp
resultSyncResultNoOperation-specific result (present on success)
errorSyncErrorNoError details (present on failure)

Example

json
{
  "messageId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "success": true,
  "timestamp": "2026-03-02T14:30:00.050Z",
  "result": {
    "type": "navigation",
    "contextId": "ctx_xyz789",
    "processed": true
  }
}

SyncResult Variants

The result field is a discriminated union on type.

ContextSyncResult

FieldTypeDescription
type"context"Discriminator
contextIdstringServer-assigned context ID
versionnumberContext version after the operation

TabActivationResult

FieldTypeDescription
type"tab_activation"Discriminator
acknowledgedbooleanWhether the activation was recorded

NavigationResult

FieldTypeDescription
type"navigation"Discriminator
contextIdstringContext ID for the new page
processedbooleanWhether the navigation was fully processed

HeartbeatResult

FieldTypeDescription
type"heartbeat"Discriminator
serverTimestringCurrent server time (for clock sync)
configUpdateSyncConfigurationUpdated configuration, if changed server-side

SyncError

Returned when a sync operation fails.

FieldTypeRequiredDescription
typeSyncErrorTypeYesError category
messagestringYesHuman-readable error description
codestringYesMachine-readable error code
detailsobjectNoAdditional error context
retryAfternumberNoSeconds to wait before retrying (for rate limit errors)

SyncErrorType

ValueDescription
authentication_errorInvalid or expired authentication token
authorization_errorUser lacks permission for this operation
validation_errorPayload failed schema validation
not_foundReferenced resource does not exist
conflictOperation conflicts with current state (e.g. stale version)
rate_limitToo many requests; check retryAfter
server_errorInternal server error
connection_errorWebSocket connection issue

BatchSyncMessage

Send multiple sync operations in a single request via the REST API.

FieldTypeRequiredDescription
idstringYesUnique batch identifier (UUID v4)
userIdstringYesAuthenticated user ID
extensionIdstringYesExtension instance identifier
timestampstringYesISO 8601 timestamp
messagesSyncMessage[]YesArray of individual sync messages

BatchSyncResponse

Response to a BatchSyncMessage.

FieldTypeRequiredDescription
messageIdstringYesID of the original BatchSyncMessage
timestampstringYesISO 8601 server timestamp
resultsSyncResponse[]YesIndividual results for each message (in order)
partialSuccessbooleanYestrue if some messages succeeded and others failed

When partialSuccess is true, the HTTP status code is 207 Multi-Status. Check individual results entries for per-message success/failure.


SyncConfiguration

Server-provided configuration for the extension sync behavior. Returned in heartbeat responses when configuration changes.

FieldTypeDefaultDescription
heartbeatIntervalnumber30000Milliseconds between heartbeat messages
batchSizenumber50Maximum messages per batch request
batchTimeoutnumber5000Milliseconds to wait before flushing a partial batch
retryAttemptsnumber3Maximum retry attempts for failed operations
retryDelaynumber1000Base delay in milliseconds for retry backoff
enabledContextTypesstring[]["*"]Which context types to sync (e.g. ["text.selection", "page.navigation"])
privacySettingsobject{}Privacy filter overrides from the server

ConnectionState

Enum representing the WebSocket connection lifecycle.

ValueDescription
disconnectedNo active connection
connectingConnection attempt in progress
connectedConnection established and authenticated
reconnectingAttempting to re-establish a dropped connection
errorConnection failed; see ConnectionStatus.errorMessage

ConnectionStatus

Full status of the WebSocket connection.

FieldTypeDescription
stateConnectionStateCurrent connection state
lastConnectedstringISO 8601 timestamp of last successful connection
lastHeartbeatstringISO 8601 timestamp of last heartbeat sent
errorMessagestringError description if state is error
retryCountnumberNumber of consecutive reconnection attempts
queuedMessagesnumberMessages queued while disconnected

Queued messages are automatically sent in order when the connection is re-established. If the queue exceeds 1000 messages, the oldest messages are dropped.