Skip to main content

LWC Reference

Complete reference for every event, message, and Apex action available to an LWC running inside a Keelstone Screen Flow.


How LWC ↔ Keelstone communication works

LWC components run in Salesforce's domain and cannot call Office APIs directly. Keelstone bridges them through two channels:

postMessage — For real-time, synchronous document operations (read range, write data, insert file). Your LWC calls window.parent.postMessage(payload, '*') and the Keelstone taskpane executes the Office API call.

Apex Invocable Actions — For all other operations (document generation, SOQL queries, server-side PDF/chart/presentation creation). These are added to your Screen Flow as action elements. The flow passes them KeelstoneSessionId from the conversation variable.

LWC in Screen Flow

├─ window.parent.postMessage({type:'KEELSTONE_WRITE', ...})
│ ↓
│ Keelstone taskpane → Excel.run() / Word API
│ ↓
│ window.postMessage({type:'KEELSTONE_WRITE_RESULT', ...}) ← LWC receives

└─ Flow Action: KS_WriteData (keelstoneSessionId, dataJson, target)

Apex → POST app.keelstone.dev/api/excel/write

Server → socket.io → taskpane → Excel.run()

1 — Events your LWC can send to Keelstone

Send via window.parent.postMessage(payload, '*') from your LWC. The taskpane processes these synchronously. Listen for the response with window.addEventListener('message', handler).


KEELSTONE_INSERT

Inserts a base64-encoded .xlsx file as a new sheet in the workbook.

Send:

window.parent.postMessage({
type: 'KEELSTONE_INSERT',
base64: '<base64-encoded xlsx>', // required
filename: 'Report.xlsx' // optional, used as sheet name hint
}, '*');

No response event — fire and forget.


KEELSTONE_WRITE

Writes a 2D array to a range. Optionally creates an Excel Table and named range.

Send:

window.parent.postMessage({
type: 'KEELSTONE_WRITE',
data: [['Name', 'Amount'], ['Acme', 50000]], // required — 2D array, row 0 = headers
target: 'A1', // optional — cell address or named range
namedRange: true // optional — create named range (default true)
}, '*');

Response: KEELSTONE_WRITE_RESULT

{
type: 'KEELSTONE_WRITE_RESULT',
tableName: 'KS_Opportunities', // null if namedRange was false
address: 'A1:B3',
rowCount: 2 // excludes header row
}

KEELSTONE_QUERY

Runs a SOQL query server-side and writes results to a range. Relationship fields (Account.Name) are automatically flattened to dot-notation column headers.

Send:

window.parent.postMessage({
type: 'KEELSTONE_QUERY',
soql: 'SELECT Name, Account.Name, Amount FROM Opportunity WHERE StageName = \'Closed Won\'', // required
target: 'A1', // optional
includeHeaders: true // optional, default true
}, '*');

Response: KEELSTONE_QUERY_RESULT

{
type: 'KEELSTONE_QUERY_RESULT',
address: 'A1:C10',
rowCount: 9
}

KEELSTONE_GET_RANGE

Requests the current selection address and values.

Send:

window.parent.postMessage({ type: 'KEELSTONE_GET_RANGE' }, '*');

Response: KEELSTONE_RANGE_RESPONSE

{
type: 'KEELSTONE_RANGE_RESPONSE',
address: 'Sheet1!B2:D5',
values: [['Q1', 100], ['Q2', 200]] // 2D array of cell values
}

KEELSTONE_SAVE_TABLES

Reads all Excel Tables on the active sheet and POSTs their data to /api/data/save.

Send:

window.parent.postMessage({ type: 'KEELSTONE_SAVE_TABLES' }, '*');

Response: KEELSTONE_SAVE_RESULT

{
type: 'KEELSTONE_SAVE_RESULT',
saved: 42,
errors: []
}

2 — Events your LWC receives from Keelstone

These arrive automatically — no configuration required. Listen with window.addEventListener('message', handler).


KS_OFFICE_EVENT

Real-time document events forwarded by the Keelstone taskpane. Debounced at 250 ms.

{
type: 'KS_OFFICE_EVENT',
eventType: '<see table below>',
data: { /* event-specific payload */ }
}
eventTypeAppFires whendata shape
excel:selectionChangedExcelUser selects a range{ address: "Sheet1!A1:B3", values: [[...]] }
excel:changedExcelA cell value changes{ address: "A1", worksheetId: "Sheet1" }
excel:sheetActivatedExcelUser switches sheets{ worksheetId: "Sheet1" }
word:selectionChangedWordCursor moves or selection changes{ selectedText: "..." }
ppt:selectionChangedPowerPointUser selects a slide{ slides: [{ id, index, title }] }

How events reach a dialog-launched flow:

Taskpane emits ks:office-event on socket

Relay server forwards to the dialog socket for the same session

flow-host.html converts to window.postMessage({ type: 'KS_OFFICE_EVENT', ... })

Your LWC receives it via window.addEventListener('message')

For flows launched in the taskpane itself (Launch Target = Taskpane), events arrive directly without the relay.


Response events

Responses to messages you sent (section 1 above). Arrive on the same message listener.

typeTriggered byPayload
KEELSTONE_WRITE_RESULTKEELSTONE_WRITE{ tableName, address, rowCount }
KEELSTONE_RANGE_RESPONSEKEELSTONE_GET_RANGE{ address, values }
KEELSTONE_QUERY_RESULTKEELSTONE_QUERY{ address, rowCount }
KEELSTONE_SAVE_RESULTKEELSTONE_SAVE_TABLES{ saved, errors }

Listening — complete LWC pattern

// myComponent.js
connectedCallback() {
this._handler = this._onMessage.bind(this);
window.addEventListener('message', this._handler);
}

disconnectedCallback() {
window.removeEventListener('message', this._handler);
}

_onMessage(event) {
const msg = event.data;
if (!msg?.type) return;

// Office events (arrive automatically)
if (msg.type === 'KS_OFFICE_EVENT') {
const { eventType, data } = msg;
if (eventType === 'excel:selectionChanged') {
this.selectedRange = data.address;
this.selectedValues = data.values;
}
if (eventType === 'word:selectionChanged') {
this.selectedText = data.selectedText;
}
if (eventType === 'excel:sheetActivated') {
this.activeSheet = data.worksheetId;
}
return;
}

// Responses to messages you sent
switch (msg.type) {
case 'KEELSTONE_RANGE_RESPONSE':
this.activeRange = msg.address;
break;
case 'KEELSTONE_WRITE_RESULT':
this.tableName = msg.tableName;
this.recordCount = msg.rowCount;
break;
case 'KEELSTONE_QUERY_RESULT':
this.queryAddress = msg.address;
break;
case 'KEELSTONE_SAVE_RESULT':
this.savedCount = msg.saved;
break;
}
}

3 — Keelstone Apex Actions

All Keelstone actions are @InvocableMethod classes. Add them to your Screen Flow as Action elements. Each action needs a KeelstoneSessionId input (wired to the {!KeelstoneSessionId} conversation variable) unless marked otherwise.

All results include success (Boolean) and either resultJson (String) or dedicated output variables. When success is false, check errorMessage.


Excel — Reading

KS: Get Range

Returns the current selection address and values.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputStringActive session ID
resultJsonOutputString{ address, values }
successOutputBoolean

Excel — Writing

KS: Write Data to Excel

Writes a 2D JSON array to a range.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
dataJsonInputString2D array as JSON, e.g. [["Name","Amount"],["Acme",50000]]
targetInputStringTarget cell or named range, e.g. "A1"
namedRangeInputBooleanCreate a named range for the written data (default true)
resultJsonOutputString{ address, tableName, rowCount }
successOutputBoolean

KS: Query Salesforce and Write to Excel

Runs SOQL server-side and writes results to a range. Relationship fields are flattened to Account.Name column headers automatically.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
soqlInputStringSOQL query
targetInputStringTarget cell or named range
includeHeadersInputBooleanWrite column headers as first row (default true)
resultJsonOutputString{ address, rowCount }
successOutputBoolean

Excel — Charts

KS: Add Excel Chart from Range

Creates a chart from an existing data range in the workbook.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
dataRangeInputStringA1 notation, e.g. "A1:C5"
sheetNameInputStringSheet containing the range (default: active sheet)
chartTypeInputStringColumnClustered, Line, Pie, BarClustered, Area, Scatter (default ColumnClustered)
titleInputStringChart title
positionInputStringTop-left cell for chart placement, e.g. "E2"
xAxisTitleInputString
yAxisTitleInputString
chartNameInputStringName for the chart object
showLegendInputBooleanDefault true
showDataLabelsInputBooleanDefault false
resultJsonOutputString{ chartName }
successOutputBoolean

KS: Add Excel Chart from Data

Creates a chart from inline data arrays (no existing range needed).

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
labelsInputStringJSON array of category labels, e.g. '["Q1","Q2","Q3","Q4"]'
seriesInputStringJSON array of series, e.g. '[{"name":"Revenue","values":[100,200,150,300]}]'
sheetNameInputStringSheet to write data and chart to
chartTypeInputStringSee above (default ColumnClustered)
titleInputString
dataTargetInputStringCell where data should be written, e.g. "A1"
chartPositionInputStringCell for chart placement
xAxisTitleInputString
yAxisTitleInputString
showLegendInputBooleanDefault true
showDataLabelsInputBooleanDefault false
chartNameInputString
resultJsonOutputString{ chartName, dataRange }
successOutputBoolean

KS: List Excel Charts

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
resultJsonOutputString{ charts: [{ name, sheetName }] }
successOutputBoolean

KS: Delete Excel Chart

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
chartNameInputStringName returned by Add Chart
sheetNameInputString
resultJsonOutputString{ ok: true }
successOutputBoolean

Excel — Comments

KS: Get Excel Cell Comments

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
addressInputStringCell ("B3"), range ("A1:D10"), or omit for all workbook comments
resultJsonOutputString{ comments: [{ id, author, authorEmail, text, created, resolved, replies: [] }] }
successOutputBoolean

KS: Add Excel Cell Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
addressInputStringTarget cell, e.g. "B3"
textInputStringComment body
resultJsonOutputString{ id, author, created }
successOutputBoolean

KS: Reply to Excel Cell Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
commentIdInputStringID from Get Cell Comments
textInputString
resultJsonOutputString{ id, author, created }
successOutputBoolean

KS: Resolve Excel Cell Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
commentIdInputString
resolvedInputBooleantrue to resolve, false to reopen
resultJsonOutputString{ ok, resolved }
successOutputBoolean

KS: Delete Excel Cell Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
commentIdInputString
resultJsonOutputString{ ok: true }
successOutputBoolean

Excel/Word — Document Properties

Document properties are key/value strings stored inside the file. Keelstone uses _ks_doc_id and _ks_template_key internally — those keys are reserved and cannot be read or written by these actions.

KS: Get Document Property

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
keyInputStringProperty key
resultJsonOutputString{ key, value }
successOutputBoolean

KS: Set Document Property

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
keyInputStringProperty key (reserved keys _ks_doc_id, _ks_template_key are blocked)
valueInputStringProperty value
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Get Document Settings

Returns all non-reserved document properties as a JSON object. Use this to read any custom metadata stored in the document by previous flow runs.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
documentTypeInputString"Word" or "Excel" (default "Word")
settingsJsonOutputStringJSON object of all non-internal properties, e.g. { recordId: "001...", status: "draft" }
successOutputBoolean

Word — Reading

KS: Get Word Document Text

Returns the full body text of the open Word document.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
resultJsonOutputString{ text: "Full document body..." }
successOutputBoolean

KS: Get Word Selection Comments

Returns comments anchored to the current cursor selection.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
resultJsonOutputString{ comments: [{ id, author, text, created, resolved }] }
successOutputBoolean

Word — Writing

KS: Insert at Cursor (Word)

Inserts content at the current cursor position.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
contentInputStringText, HTML, or OOXML to insert
contentTypeInputString"text" (default), "html", or "ooxml"
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Update Word Content Control

Replaces the text inside a tagged Content Control.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
tagInputStringContent Control tag, e.g. "SF_Indemnification_Clause"
textInputStringReplacement text
resultJsonOutputString{ ok: true }
successOutputBoolean

Word — Comments

KS: Add Word Comment

Adds a comment anchored to the current selection.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
textInputStringComment body
resultJsonOutputString{ id, author, created }
successOutputBoolean

KS: Reply to Word Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
commentIdInputString
textInputString
resultJsonOutputString{ id, author, created }
successOutputBoolean

KS: Resolve Word Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
commentIdInputString
resolvedInputBooleantrue to resolve, false to reopen
resultJsonOutputString
successOutputBoolean

KS: Delete Word Comment

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
commentIdInputString
resultJsonOutputString{ ok: true }
successOutputBoolean

Word — Keywords

KS: Scan Keywords

Scans the open Word document for a list of keywords and returns their positions.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
keywordsInputList<String>Keywords to search for
resultJsonOutputString{ matches: [{ keyword, count, paragraphIndexes }] }
successOutputBoolean

PowerPoint

KS: Get PowerPoint Slide Count

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
resultJsonOutputString{ count: 5 }
successOutputBoolean

KS: Get PowerPoint Shapes

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputInteger0-based slide index (default 0)
resultJsonOutputString{ shapes: [{ id, name, type, left, top, width, height }] }
successOutputBoolean

KS: Add PowerPoint Slide

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
resultJsonOutputString{ index }
successOutputBoolean

KS: Delete PowerPoint Slide

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputInteger0-based index
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Add PowerPoint Text Box

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
textInputStringText content
slideIndexInputIntegerDefault 0
leftInputDecimalLeft position in inches (default 1)
topInputDecimalTop position in inches (default 1)
widthInputDecimalWidth in inches (default 8)
heightInputDecimalHeight in inches (default 2)
resultJsonOutputString{ id, name }
successOutputBoolean

KS: Add PowerPoint Image

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
base64InputStringBase64-encoded image (PNG, JPG, GIF, BMP)
slideIndexInputIntegerDefault 0
leftInputDecimalDefault 1 inch
topInputDecimalDefault 1 inch
widthInputDecimalDefault 3 inches
heightInputDecimalDefault 3 inches
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Get PowerPoint Slide Text

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputIntegerDefault 0
resultJsonOutputString{ shapes: [{ name, text }] }
successOutputBoolean

KS: Set PowerPoint Shape Text

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputIntegerDefault 0
shapeNameInputStringShape name from Get Shapes
textInputString
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Delete PowerPoint Shape

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputIntegerDefault 0
shapeNameInputString
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Export PowerPoint Slide

Exports a single slide as a .pptx file. Requires PowerPoint API set 1.8 (Microsoft 365 desktop, June 2024+).

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputInteger0-based index
resultJsonOutputString{ base64 } — base64 .pptx
successOutputBoolean

KS: Get PowerPoint Slide Image

Renders a slide to a PNG image.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputIntegerDefault 0
widthInputIntegerImage width in pixels
heightInputIntegerImage height in pixels
resultJsonOutputString{ base64 } — base64 PNG
successOutputBoolean

KS: Add PowerPoint Slide Tag

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputIntegerDefault 0
keyInputStringTag key
valueInputStringTag value
resultJsonOutputString{ ok: true }
successOutputBoolean

KS: Get PowerPoint Slide Tags

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
slideIndexInputIntegerDefault 0
resultJsonOutputString{ tags: { key: value, ... } }
successOutputBoolean

KS: Insert PowerPoint Slides

Inserts slides from a base64 .pptx file into the current presentation.

VariableDirectionTypeRequiredDescription
keelstoneSessionIdInputString
base64InputStringBase64 .pptx file
sourceSlideIdsInputList<String>Specific slide IDs to insert; omit for all slides
resultJsonOutputString{ ok: true }
successOutputBoolean

Document Generation — No taskpane required

These actions call the Keelstone server directly from Apex. The Office add-in does not need to be open for them to run. Useful for automating document creation from record-triggered flows or scheduled flows.

KS: Generate Document from Template

Merges a Word or Excel template with Salesforce record data and saves the output to Salesforce Files.

VariableDirectionTypeRequiredDescription
templateKeyInputStringTemplate_Key__c slug from a Keelstone_Template__c record — portable across orgs
contextJsonInputStringMerge context as a JSON string. Build with KS: Build Merge Context + KS: Add Table, a custom Apex class, or an LWC.
mergeDataInputStringExtra merge values as JSON — merged on top of contextJson at highest priority, e.g. '{"today":"April 14, 2026"}'
filenameInputStringOutput filename (extension determines format)
linkedEntityIdInputStringSave the file linked to this record ID
externalLinkInputBooleanGenerate a public download URL
contentDocumentIdOutputStringContentDocumentId of the generated file
documentUrlOutputStringPublic URL (when externalLink is true)
templateKeyOutputStringEcho of input — useful for chaining or storing in the document
successOutputBoolean
errorMessageOutputString

Merge priority (lowest → highest): contextJsonmergeData JSON

KS: Build Merge Context

Serialises a primary SObject record to a context JSON string for passing to KS: Add Table and then KS: Generate Document.

VariableDirectionTypeRequiredDescription
recordInputSObject
contextJsonOutputStringJSON representation of the record
successOutputBoolean
errorMessageOutputString

KS: Add Table to Context

Adds a related record collection to an existing context JSON string. Chain multiple calls to add multiple tables.

VariableDirectionTypeRequiredDescription
contextJsonInputStringContext from KS: Build Merge Context or a prior KS: Add Table
recordsInputList<SObject>Related records to add
tableNameInputStringKey name for this table in the context (default "items")
contextJsonOutputStringUpdated context JSON
successOutputBoolean
errorMessageOutputString

KS: Fill PDF Form

Fills an AcroForm PDF template with Salesforce record field values and saves to Files.

VariableDirectionTypeRequiredDescription
templateIdInputStringContentDocumentId of the PDF template
recordInputSObjectRecord whose API field names match the PDF form fields
filenameInputString
linkedEntityIdInputString
externalLinkInputBoolean
flattenInputBooleanFlatten form fields after filling (default false)
contentDocumentIdOutputString
documentUrlOutputString
successOutputBoolean
errorMessageOutputString

KS: Generate PDF

Generates a PDF from a pdfmake document definition.

VariableDirectionTypeRequiredDescription
docDefinitionJsonInputStringpdfmake docDefinition object as JSON
resultJsonOutputString{ base64, mimeType: "application/pdf" }
successOutputBoolean

KS: Generate PowerPoint Presentation

Generates a .pptx file from a JSON slide definition array. No PowerPoint add-in required.

VariableDirectionTypeRequiredDescription
slidesJsonInputStringJSON array of slide objects — each can have title, body, bullets[], imageBase64, backgroundColor
titleInputStringPresentation metadata title
layoutInputStringpptxgenjs layout name, e.g. "LAYOUT_WIDE" (default) or "LAYOUT_16x9"
resultJsonOutputString{ base64, mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation" }
successOutputBoolean

KS: Generate Chart Image

Generates a Chart.js chart as a PNG image. No Office add-in required.

VariableDirectionTypeRequiredDescription
labelsJsonInputStringJSON array of category labels, e.g. '["Q1","Q2","Q3","Q4"]'
datasetsJsonInputStringJSON array of datasets, e.g. '[{"label":"Revenue","data":[100,200,150,300]}]'
chartTypeInputStringbar, line, pie, doughnut, radar, polarArea (default bar)
titleInputStringChart title
widthInputIntegerPixels (default 800)
heightInputIntegerPixels (default 500)
resultJsonOutputString{ base64, mimeType: "image/png" }
successOutputBoolean