Documentation Index
Fetch the complete documentation index at: https://developer.kodexa.ai/llms.txt
Use this file to discover all available pages before exploring further.
The Bridge API is the interface between scripts running in the QuickJS sandbox and the Kodexa platform. Scripts access it through the kodexa.* namespace, where each sub-namespace corresponds to a capability gated by the form’s bridge permissions.
Bridge Permissions
The bridge property on a data form configures what scripts are allowed to do. The permissions array lists capability gates — a script that attempts to call a method without the required permission will receive a Permission denied error.
| Permission | Grants access to |
|---|
data:read | Read data objects, attributes, tag metadata, taxonomies |
data:write | Modify data objects and attributes |
document:read | Access the document proxy (kodexa.document) |
navigation | Focus attributes, scroll to nodes, switch views |
formState | Get and set form state values, access node refs |
http:get | HTTP GET requests via kodexa.http |
http:post | HTTP POST requests via kodexa.http and service bridge calls |
Additional bridge configuration:
apiBaseUrl — Base URL for kodexa.http and kodexa.serviceBridge calls. Defaults to "/api".
maxExecutionMs — Script execution timeout in milliseconds. Defaults to 1000.
{
"bridge": {
"permissions": ["data:read", "data:write", "navigation", "http:post"],
"apiBaseUrl": "https://api.example.com",
"maxExecutionMs": 2000
}
}
kodexa.data
Requires data:read. Methods that modify data also require data:write.
| Method | Parameters | Returns | Permission |
|---|
getDataObjects(filter?) | { path?: string, parentId?: string } | DataObject[] | data:read |
getDataObject(uuid) | uuid: string | DataObject | null | data:read |
getAttributes(dataObjectUuid) | dataObjectUuid: string | Attribute[] | data:read |
getAttribute(dataObjectUuid, path) | dataObjectUuid: string, path: string | any | data:read |
setAttribute(dataObjectUuid, path, value) | dataObjectUuid: string, path: string, value: any | void | data:write |
addDataObject(parentUuid, path) | parentUuid: string, path: string | DataObject | data:write |
deleteDataObject(uuid) | uuid: string | void | data:write |
getTagMetadata(path) | path: string | TagMetadata | null | data:read |
getTaxonomies() | — | Taxonomy[] | data:read |
// Read all line items under a parent object
const items = kodexa.data.getDataObjects({ parentId: parentUuid });
for (const item of items) {
const amount = kodexa.data.getAttribute(item.uuid, "LineItem/Amount");
kodexa.log.debug("Amount: " + amount);
}
// Set a computed total
kodexa.data.setAttribute(summaryUuid, "Invoice/Total", calculatedTotal);
kodexa.navigation
Requires navigation.
| Method | Parameters | Description |
|---|
focusAttribute(dataObjectUuid, attributePath) | dataObjectUuid: string, attributePath: string | Highlight an attribute in the document viewer |
scrollToNode(ref) | ref: string | Scroll the document viewer to a content node |
switchView(viewName) | viewName: string | Switch to a different form view |
Note that focusAttribute takes dataObjectUuid as the first parameter and attributePath as the second.
Requires formState.
| Method | Parameters | Returns | Description |
|---|
get(key) | key: string | any | Read a form state value |
set(key, value) | key: string, value: any | void | Write a form state value |
getNodeRef(ref) | ref: string | { setProps(props) } | Get a UINode by ref for dynamic prop updates |
Form state is ephemeral — it persists for the lifetime of the form session but is not saved to the server. Use it for UI-only concerns like toggling visibility, tracking selection state, or passing values between scripts.
// Toggle a detail panel
const expanded = kodexa.form.get("detailExpanded") || false;
kodexa.form.set("detailExpanded", !expanded);
// Dynamically update a node's props
const node = kodexa.form.getNodeRef("statusLabel");
node.setProps({ text: "Validated", variant: "success" });
kodexa.document
Requires document:read. The writable snapshot also requires data:write.
| Method | Returns | Description |
|---|
snapshot() | ScriptDocumentProxy | Read-only proxy over the current document data |
writableSnapshot() | ScriptDocumentProxy | Writable proxy — mutations flow through the workspace store |
The ScriptDocumentProxy exposes getAllDataObjects(), getDataObjectByUUID(uuid), and getDataObjectsByPath(path). Each returns ScriptDataObjectProxy instances with methods like getAttributes(), getAttribute(label), getChildren(), and getPath(). Writable proxies additionally support addAttribute(), addChild(), and setValue() on attributes.
This API is separate from loadDocument() available in inline or named scripts. kodexa.document provides Bridge API context tied to the current workspace session; loadDocument() is for standalone script execution.
kodexa.http
Requires http:get for GET requests, http:post for POST requests. Both are async.
| Method | Parameters | Returns |
|---|
get(path) | path: string | Promise<any> |
post(path, body?) | path: string, body?: any | Promise<any> |
Requests are sent to apiBaseUrl + path. The base URL defaults to "/api" if not configured.
// Call an external validation endpoint
const result = await kodexa.http.post("/validate", {
invoiceNumber: invoiceNum,
vendorId: vendorId
});
if (!result.valid) {
kodexa.log.warn("Validation failed: " + result.reason);
}
kodexa.serviceBridge
Requires http:post.
| Method | Parameters | Returns |
|---|
call(ref, endpoint, body?) | ref: string, endpoint: string, body?: any | Promise<any> |
Service bridges are named proxy endpoints that connect the platform to external APIs with centralized authentication. The ref is the bridge slug (e.g., "acme-logistics/carrier-lookup"), and endpoint is the endpoint name defined in the bridge YAML.
The bridge manages an X-Bridge-Context header for session caching. On the first call, no context header is sent; the server runs any configured initScript and returns context in the response header. Subsequent calls attach the cached context, skipping re-initialization. Context expires after a configurable TTL (default 3600 seconds).
const carriers = await kodexa.serviceBridge.call(
"acme-logistics/carrier-lookup",
"lookup-carrier",
{ scac: scacCode }
);
kodexa.log
No permission required.
| Method | Parameters |
|---|
debug(message) | message: string |
warn(message) | message: string |
error(message) | message: string |
All log output is prefixed with [DataFormV2] and routed to the browser console.
Service Bridges on Panels
In addition to imperative kodexa.serviceBridge.call() from scripts, panels support declarative service bridge integration through the serviceBridge prop on v2:panel. This allows a component to declare an external API dependency without writing script code.
ServiceBridgeConfig
| Property | Type | Description |
|---|
ref | string | Bridge reference (e.g., "acme-logistics/carrier-lookup") |
endpoint | string | Endpoint name from the bridge YAML |
method | "GET" | "POST" | HTTP method, defaults to POST |
requestMapping | Record<string, string> | Maps data attribute paths to request fields |
responseMapping | ServiceBridgeResponseMapping | Controls how the response maps back to UI or data |
triggerOn | string[] | Attribute paths that trigger a re-call when values change |
ServiceBridgeResponseMapping
| Property | Type | Description |
|---|
value | string | Path to extract option value from each response item |
label | string | Path or expression for the option label (supports concatenation like "code + ' - ' + description") |
description | string | Path or expression for hint text shown below the label in dropdowns |
autoSelect | string | Auto-select a single best-match field from the response |
attributes | Array<{ from, to }> | Map response fields to data attributes (from: response path, to: attribute path) |
How It Works
When any attribute listed in triggerOn changes, the panel reads the current values from requestMapping, calls the service bridge endpoint, and maps the response back using responseMapping. This creates a reactive loop: user edits a field, the bridge fetches updated data, and dependent fields populate automatically.
{
"component": "v2:panel",
"props": {
"title": "Carrier Details",
"serviceBridge": {
"ref": "acme-logistics/carrier-lookup",
"endpoint": "lookup-carrier",
"requestMapping": {
"scac": "Shipment/CarrierSCAC"
},
"responseMapping": {
"value": "carrierId",
"label": "scac + ' - ' + carrierName",
"attributes": [
{ "from": "carrierName", "to": "Shipment/CarrierName" },
{ "from": "dotNumber", "to": "Shipment/DOTNumber" }
]
},
"triggerOn": ["Shipment/CarrierSCAC"]
}
}
}
In this example, when the user enters a SCAC code, the panel calls the carrier lookup endpoint and auto-populates the carrier name and DOT number fields from the response.
v2:serviceBridgeView
A container component that calls a service bridge endpoint and makes the response available to its children through the data context. Unlike the panel serviceBridge prop (which maps responses back to attributes), v2:serviceBridgeView is designed for read-only display — rendering bridge responses as tables, markdown, labels, or any combination of child components.
How It Works
- The component resolves the bridge slug to an ID via the platform’s
/api/resolve endpoint.
- It POSTs the
params to the bridge proxy endpoint (/api/service-bridges/{id}/proxy/{endpoint}).
- If a
transform expression is provided, the response is reshaped using JSONata.
- The result is injected into a scoped
DataContextV2 as ctx.$bridgeResult, along with ctx.$bridgeLoading and ctx.$bridgeError.
- Children render using bindings that reference these context variables.
The component handles loading and error states automatically — children are only rendered once data is available.
Props
| Prop | Type | Default | Description |
|---|
| bridgeRef | string | required | Service bridge URI (e.g., "service-bridge://acme/rate-lookup" or "acme/rate-lookup") |
| endpoint | string | required | Endpoint name defined in the bridge configuration |
| params | Record | — | Request body sent to the bridge (typically provided via bindings) |
| transform | string | — | JSONata expression applied to the response before injecting into context |
Context Variables
Children of v2:serviceBridgeView receive these additional context variables:
| Variable | Type | Description |
|---|
ctx.$bridgeResult | any | The bridge response (after optional JSONata transform) |
ctx.$bridgeLoading | boolean | true while the request is in flight |
ctx.$bridgeError | string | Error message if the request failed |
All existing context variables (ctx.dataObjects, ctx.tagMetadataMap, etc.) remain available — the bridge context is additive.
Reactive Parameters
When params is provided via bindings, the component re-calls the bridge whenever the bound values change. This creates a reactive chain: the user edits an attribute, the binding expression re-evaluates, new params are sent to the bridge, and children re-render with fresh data.
When referencing attributes in binding expressions, the tag property is the leaf name (e.g., originZip), not the full taxonomy path (shipment/originZip). The full path is available as path on the attribute. Use a.tag === 'originZip' or a.path === 'shipment/originZip' depending on which you need.
Example: Table from Bridge Response
Call a rate lookup endpoint, transform the response with JSONata, and render the results as a filterable AG Grid table:
component: v2:serviceBridgeView
props:
bridgeRef: "service-bridge://acme/rate-lookup"
endpoint: "get-rates"
transform: |
results.{
"Carrier": carrier,
"Rate": "$" & $string(rate),
"Transit": transit & " days"
}
bindings:
params: |
{
originZip: ctx.dataObjects[0]?.attributes?.find(
a => a.tag === 'originZip'
)?.stringValue,
destZip: ctx.dataObjects[0]?.attributes?.find(
a => a.tag === 'destZip'
)?.stringValue,
weight: ctx.dataObjects[0]?.attributes?.find(
a => a.tag === 'weight'
)?.numericValue
}
children:
- component: v2:dataTable
bindings:
rows: "ctx.$bridgeResult"
props:
filterable: true
columns:
- field: Carrier
title: Carrier Name
- field: Rate
title: Rate
width: 120
- field: Transit
title: Transit Time
width: 120
Example: Markdown Summary
Fetch a report from a bridge and render it as markdown:
component: v2:serviceBridgeView
props:
bridgeRef: "service-bridge://acme/analysis"
endpoint: "get-report"
bindings:
params: |
{
invoiceId: ctx.dataObjects[0]?.attributes?.find(
a => a.tag === 'id'
)?.stringValue
}
children:
- component: v2:markdown
bindings:
content: "ctx.$bridgeResult?.report"
Example: Mixed Content
Combine multiple child components to render different parts of the bridge response:
component: v2:serviceBridgeView
props:
bridgeRef: "service-bridge://acme/vendor-check"
endpoint: "validate"
bindings:
params: |
{
vendorCode: ctx.dataObjects[0]?.attributes?.find(
a => a.tag === 'vendorCode'
)?.stringValue
}
children:
- component: v2:label
bindings:
text: "'Vendor: ' + (ctx.$bridgeResult?.vendorName ?? 'Unknown')"
- component: v2:dataTable
bindings:
rows: "ctx.$bridgeResult?.recentOrders"
props:
filterable: true
columns:
- field: orderNumber
title: Order #
- field: date
title: Date
- field: amount
title: Amount
- component: v2:markdown
bindings:
content: "ctx.$bridgeResult?.notes"
The transform prop accepts any valid JSONata expression. Common patterns:
| Pattern | Expression | Description |
|---|
| Extract a nested array | response.data.items | Drill into the response structure |
| Reshape objects | items.{ "Name": name, "Total": "$" & $string(price * qty) } | Create new fields from existing ones |
| Filter rows | items[status = "active"] | Only include rows matching a condition |
| Aggregate | $sum(items.amount) | Compute totals or other aggregations |
| Sort | items^(>amount) | Sort results by a field |
| String formatting | items.{ "Display": firstName & " " & lastName } | Concatenate fields |
If the transform is omitted, the raw response is passed through as ctx.$bridgeResult.
The JSONata transform runs client-side after the response is received. For large responses, consider using the bridge’s postReplyScript to filter server-side before the data reaches the browser.
Comparison: Panel serviceBridge vs serviceBridgeView
| Feature | Panel serviceBridge prop | v2:serviceBridgeView |
|---|
| Purpose | Map bridge response to data attributes | Display bridge response as read-only content |
| Trigger | Attribute path changes (triggerOn) | Binding expression changes (reactive params) |
| Response handling | responseMapping writes to attributes | Children render from ctx.$bridgeResult |
| Rendering | No built-in display | Children render tables, markdown, labels, etc. |
| Script required | No | No |
| Use case | Auto-populate fields from external data | Show reference data, reports, lookup tables |