Skip to main content

POST /api/docs/generate-from-key

Resolves a Keelstone template by its developer key, merges an arbitrary JSON data object into it, and returns the result as base64. The data object can be assembled from any combination of sources — Salesforce records, external REST API responses, computed values, or all three.

Unlike POST /api/docs/generate, this endpoint fetches the template file from Salesforce automatically using the caller's session — your LWC never handles template base64 directly.

Base URL: https://app.keelstone.dev
Authentication: Session-based (keelstoneSessionId in request body, forwarded via ksCall)

Request

POST /api/docs/generate-from-key
Content-Type: application/json
{
templateKey: string; // Template_Key__c on a Keelstone_Template__c record
data: object; // Any JSON-serializable merge context
filename?: string; // Output filename, e.g. 'Report.xlsx' or 'Quote.docx'
linkedEntityId?: string; // Salesforce record ID to attach the generated file to
outputFormat?: string; // 'pdf' to convert the output
linkedSharePointPath?: string; // SharePoint folder to upload the result to
}
FieldTypeRequiredDescription
templateKeystringYesTemplate_Key__c value on the Keelstone_Template__c record
dataobjectYesMerge context. Keys become template tokens ({Name}, {#items}{/items}, etc.)
filenamestringNoOutput filename. Extension determines format — .docx, .xlsx, or .pdf
linkedEntityIdstringNoIf provided, the generated file is uploaded and linked to this Salesforce record ID
outputFormatstringNoPass 'pdf' to convert the output regardless of template format
linkedSharePointPathstringNoSharePoint folder path to upload the generated file to (requires SharePoint configured in Setup)

Response

200 OK

{
"base64": "<base64-encoded merged file>",
"contentDocumentId": "069...",
"sharePointFileUrl": "https://contoso.sharepoint.com/..."
}

contentDocumentId is only present when linkedEntityId was supplied and the upload succeeded. sharePointFileUrl is only present when linkedSharePointPath was supplied and the SharePoint upload succeeded.

400 Bad Request — missing templateKey or data

{ "error": "templateKey and data are required" }

403 ForbiddenlinkedSharePointPath was supplied but the org is not on Pro

{ "error": "SharePoint integration requires the Keelstone Pro plan or higher." }

404 Not Found — no active template with that key

{ "error": "Template 'my-key' not found" }

Using from an LWC

The preferred way to call this endpoint is via ksGenerateFromData() on KSExcel or KSWord, which wraps ksCall and handles the session header automatically.

import { KSExcel } from 'kstone/api';

export default class QuoteGenerator extends KSExcel {
@api keelstoneSessionId;
@api recordId;

async handleGenerate() {
// Salesforce data from an Apex wire or imperative call
const sfRecord = await getAccountData({ recordId: this.recordId });

// External REST data — any endpoint
const pricing = await fetch('https://api.example.com/pricing').then(r => r.json());

// Assemble — the server accepts whatever shape you send
const result = await this.ksGenerateFromData(
'account-report',
{ ...sfRecord, ...pricing },
{ filename: 'Account Report.xlsx', linkedEntityId: this.recordId }
);

// result.contentDocumentId — Salesforce File ID of the generated workbook
}
}

See ksGenerateFromData on KSExcel and KSWord for the full method signature.

Data object and token mapping

The data object maps directly to merge tokens in the template file:

// data object assembled in LWC
{
Name: 'Acme Corp',
Industry: 'Technology',
Owner: { Name: 'Jane Smith' },
lineItems: [
{ description: 'Subscription', amount: 1200 },
{ description: 'Support', amount: 300 },
],
generatedDate: new Date().toLocaleDateString(),
}
// Word / Excel template tokens
{Name} → "Acme Corp"
{Industry} → "Technology"
{Owner.Name} → "Jane Smith"
{generatedDate} → "5/8/2026"

// Loop over array
{#lineItems}{description} — ${amount}{/lineItems}

Nested objects resolve to dot-notation paths. Arrays map to docxtemplater loop blocks ({#key}…{/key}). The server imposes no schema — the LWC is responsible for assembling the merge context.

Template key injection

The server automatically writes a _ks_template_key custom document property into the generated file. This allows the Keelstone taskpane to recognize which template produced the document and scope visible actions accordingly. No extra configuration is required.

Calling from Apex

For server-to-server generation without an active LWC session, use the KS_GenerateDocument invocable action or call POST /api/docs/generate directly (providing templateBase64 yourself).

For batch generation of many documents in a single Apex transaction, use POST /api/docs/generate-bulk via KS_BulkGenerateDocument.generateAll() — one callout for N documents, no DML required on the Apex side.

Want to use a template stored in SharePoint instead of Salesforce Files? See POST /api/docs/generate-from-sharepoint-template.