Skip to content

Worker Socket Protocol

App workers talk to the Lombok platform over a single authenticated Socket.IO connection. Every platform capability a worker needs — emitting events, minting user tokens, signing storage URLs, running Docker jobs, managing tasks and triggers — is expressed as a typed request/response message over that socket.

This page is the reference for that message contract. It is derived directly from the schemas in @lombokapp/types (packages/types/src/app-socket-message-schemas.ts) and the worker SDK (packages/app-worker-sdk/src/app-worker-sdk.ts).

Most app developers do not send these messages by hand — the App Worker SDK exposes a typed method for each one. This reference documents the wire contract those methods implement.

AspectValue
ProtocolSocket.IO (request/response via acknowledgement)
DirectionWorker → platform
Socket eventAPP_API
Call stylesocket.timeout(ms).emitWithAck('APP_API', { name, data })
Default timeout30000 ms, overridable per call via { timeoutMs }

Every call sends a single request envelope and resolves with a single response envelope.

Every request is the same envelope, discriminated by name:

{
name: AppSocketMessageName,
data: unknown
}

data is validated against the schema registered for name.

Every response is a discriminated union of a success result or an error:

{ result: <result for this message> }
// or
{ error: AppSocketResponseError }

AppSocketResponseError has this structure:

| Field | Type | Notes | | ---------- | -------- | --------------------------- | --------------------------- | | code | number | string | Machine-readable error code | | message | string | Human-readable message | | details? | object | Optional structured context |

There are 24 message names. They are grouped below by domain.

MessageSDK method
EMIT_EVENTemitEvent
SAVE_LOG_ENTRYsaveLogEntry

EMIT_EVENT — emits an app-defined event into the platform event bus. The eventIdentifier uses the bare app-event format (^[a-z_]+$), not a core:-prefixed platform event name.

// request
{
eventIdentifier: EventIdentifier,
data: JsonObject,
targetUserId?: uuid,
targetLocation?: { folderId: string, objectKey?: string }
}
// result
{ success: boolean }

SAVE_LOG_ENTRY

// request
{
message: string,
level: 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR',
targetLocation?: { folderId: string, objectKey?: string },
data?: JsonObject
}
// result
null
MessageSDK method
GET_CONTENT_SIGNED_URLSgetContentSignedUrls
GET_METADATA_SIGNED_URLSgetMetadataSignedUrls
UPDATE_CONTENT_METADATAupdateContentMetadata
GET_APP_STORAGE_SIGNED_URLSgetAppStorageSignedUrls

GET_CONTENT_SIGNED_URLS

// request: array of
{ folderId: string, objectKey: string, method: SignedURLsRequestMethod }
// result: array of
{ url: string, folderId: string, objectKey: string }

GET_METADATA_SIGNED_URLS

// request: array of
{
folderId: string,
objectKey: string,
contentHash: string,
metadataHash: string,
method: SignedURLsRequestMethod
}
// result: array of
{ url: string, folderId: string, objectKey: string }

UPDATE_CONTENT_METADATA

// request: array of
{
folderId: string,
objectKey: string,
hash: string,
metadata: Record<string, MetadataEntry>
}
// result
null

GET_APP_STORAGE_SIGNED_URLS

// request: array of
{ objectKey: string, method: SignedURLsRequestMethod }
// result
string[]
MessageSDK method
MINT_APP_USER_TOKENmintAppUserToken
// request
{
userId: uuid,
platformAccess?: boolean,
extra?: JsonObject
}
// result
{ accessToken: string, refreshToken: string }
MessageSDK method
GET_LATEST_DB_CREDENTIALSgetLatestDbCredentials
// request
undefined
// result
{
host: string,
port: number,
user: string,
password: string,
database: string,
ssl: boolean
}

Query execution itself is not part of this socket contract. Workers use these credentials to connect directly to Postgres.

MessageSDK method
GET_APP_CUSTOM_SETTINGSgetAppCustomSettings
PATCH_APP_CUSTOM_SETTINGSpatchAppCustomSettings
// GET_APP_CUSTOM_SETTINGS
{ userId: string } -> { values: Record<string, unknown> }
// PATCH_APP_CUSTOM_SETTINGS
{ userId: string, values: Record<string, unknown> } -> { success: boolean }
MessageSDK method
GET_APP_TASKgetAppTask
TRIGGER_APP_TASKtriggerAppTask
REPORT_TASK_PROGRESSreportTaskProgress

GET_APP_TASK

{ taskId: uuid, targetUserId?: uuid } -> TaskDTO

TRIGGER_APP_TASK

{
taskIdentifier: string,
inputData: JsonObject,
correlationKey?: string,
outputLocation?: { folderId: string, prefix: string | null },
dontStartBefore?: { timestamp: ISODateTime } | { delayMs: number },
targetLocation?: { folderId: string, objectKey?: string },
targetUserId?: uuid,
onComplete?: TaskOnCompleteConfig[],
onProgress?: TaskOnProgressConfig[],
storageAccessPolicy?: StorageAccessPolicy
} -> { taskId: string }

REPORT_TASK_PROGRESS

{
taskId: uuid,
progressReport: {
code?: string,
details?: TaskProgressDetails,
message?: TaskProgressMessage,
timestamp?: string,
executorMetadata?: ExecutorMetadata
}
} -> { success: boolean }
MessageSDK method
REGISTER_APP_TRIGGERregisterAppTrigger
UNREGISTER_APP_TRIGGERunregisterAppTrigger
LIST_APP_TRIGGERSlistAppTriggers
// REGISTER_APP_TRIGGER
{ trigger: RegisterableTriggerConfig } -> { triggerId: string }
// UNREGISTER_APP_TRIGGER
{ triggerId: uuid } -> { success: boolean }
// LIST_APP_TRIGGERS
{ kind?: 'event' | 'schedule' } -> {
triggers: {
id: string,
kind: 'event' | 'schedule',
definition: RegisterableTriggerConfig
}[]
}
MessageSDK method
EXECUTE_APP_DOCKER_JOBexecuteAppDockerJob
EXECUTE_APP_DOCKER_JOB_ASYNCexecuteAppDockerJobAsync

Shared request shape:

{
profileIdentifier: string,
jobIdentifier: string,
jobData: JsonObject,
storageAccessPolicy?: StorageAccessPolicy,
containerId?: string,
targetUserId?: string
}

EXECUTE_APP_DOCKER_JOB waits for execution and returns one of the defined submit/execute outcomes. EXECUTE_APP_DOCKER_JOB_ASYNC returns once submission completes.

MessageSDK method
DESTROY_APP_DOCKER_CONTAINERSdestroyAppDockerContainers
RESOLVE_APP_DOCKER_CONTAINERresolveAppDockerContainer
INSPECT_APP_DOCKER_CONTAINERinspectAppDockerContainer
START_APP_DOCKER_CONTAINERstartAppDockerContainer

These cover destroy, resolve, inspect, and start operations for app-managed containers.

MessageSDK method
CREATE_BRIDGE_TUNNELcreateBridgeTunnel
DELETE_BRIDGE_TUNNELdeleteBridgeTunnel

CREATE_BRIDGE_TUNNEL opens a tunnel and returns session credentials and URLs. DELETE_BRIDGE_TUNNEL closes it.

Message nameSDK methodDomain
EMIT_EVENTemitEventEvents / logging
SAVE_LOG_ENTRYsaveLogEntryEvents / logging
GET_CONTENT_SIGNED_URLSgetContentSignedUrlsContent / storage
GET_METADATA_SIGNED_URLSgetMetadataSignedUrlsContent / storage
UPDATE_CONTENT_METADATAupdateContentMetadataContent / storage
GET_APP_STORAGE_SIGNED_URLSgetAppStorageSignedUrlsContent / storage
MINT_APP_USER_TOKENmintAppUserTokenIdentity
GET_LATEST_DB_CREDENTIALSgetLatestDbCredentialsDatabase
GET_APP_CUSTOM_SETTINGSgetAppCustomSettingsApp settings
PATCH_APP_CUSTOM_SETTINGSpatchAppCustomSettingsApp settings
GET_APP_TASKgetAppTaskTasks
TRIGGER_APP_TASKtriggerAppTaskTasks
REPORT_TASK_PROGRESSreportTaskProgressTasks
REGISTER_APP_TRIGGERregisterAppTriggerTriggers
UNREGISTER_APP_TRIGGERunregisterAppTriggerTriggers
LIST_APP_TRIGGERSlistAppTriggersTriggers
EXECUTE_APP_DOCKER_JOBexecuteAppDockerJobDocker jobs
EXECUTE_APP_DOCKER_JOB_ASYNCexecuteAppDockerJobAsyncDocker jobs
DESTROY_APP_DOCKER_CONTAINERSdestroyAppDockerContainersDocker containers
RESOLVE_APP_DOCKER_CONTAINERresolveAppDockerContainerDocker containers
INSPECT_APP_DOCKER_CONTAINERinspectAppDockerContainerDocker containers
START_APP_DOCKER_CONTAINERstartAppDockerContainerDocker containers
CREATE_BRIDGE_TUNNELcreateBridgeTunnelBridge tunnels
DELETE_BRIDGE_TUNNELdeleteBridgeTunnelBridge tunnels
  • Referenced types such as TaskDTO, StorageAccessPolicy, RegisterableTriggerConfig, and progress/detail objects are defined elsewhere in @lombokapp/types and are intentionally summarized here.
  • The message set is fixed by the AppSocketMessage enum. Workers cannot invent new message names.