Skip to main content

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.
PermissionGrants access to
data:readRead data objects, attributes, tag metadata, taxonomies
data:writeModify data objects and attributes
document:readAccess the document proxy (kodexa.document)
navigationFocus attributes, scroll to nodes, switch views
formStateGet and set form state values, access node refs
http:getHTTP GET requests via kodexa.http
http:postHTTP 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.
MethodParametersReturnsPermission
getDataObjects(filter?){ path?: string, parentId?: string }DataObject[]data:read
getDataObject(uuid)uuid: stringDataObject | nulldata:read
getAttributes(dataObjectUuid)dataObjectUuid: stringAttribute[]data:read
getAttribute(dataObjectUuid, path)dataObjectUuid: string, path: stringanydata:read
setAttribute(dataObjectUuid, path, value)dataObjectUuid: string, path: string, value: anyvoiddata:write
addDataObject(parentUuid, path)parentUuid: string, path: stringDataObjectdata:write
deleteDataObject(uuid)uuid: stringvoiddata:write
getTagMetadata(path)path: stringTagMetadata | nulldata: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.
MethodParametersDescription
focusAttribute(dataObjectUuid, attributePath)dataObjectUuid: string, attributePath: stringHighlight an attribute in the document viewer
scrollToNode(ref)ref: stringScroll the document viewer to a content node
switchView(viewName)viewName: stringSwitch to a different form view
Note that focusAttribute takes dataObjectUuid as the first parameter and attributePath as the second.

kodexa.form

Requires formState.
MethodParametersReturnsDescription
get(key)key: stringanyRead a form state value
set(key, value)key: string, value: anyvoidWrite 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.
MethodReturnsDescription
snapshot()ScriptDocumentProxyRead-only proxy over the current document data
writableSnapshot()ScriptDocumentProxyWritable 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.
MethodParametersReturns
get(path)path: stringPromise<any>
post(path, body?)path: string, body?: anyPromise<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.
MethodParametersReturns
call(ref, endpoint, body?)ref: string, endpoint: string, body?: anyPromise<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.
MethodParameters
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

PropertyTypeDescription
refstringBridge reference (e.g., "acme-logistics/carrier-lookup")
endpointstringEndpoint name from the bridge YAML
method"GET" | "POST"HTTP method, defaults to POST
requestMappingRecord<string, string>Maps data attribute paths to request fields
responseMappingServiceBridgeResponseMappingControls how the response maps back to UI or data
triggerOnstring[]Attribute paths that trigger a re-call when values change

ServiceBridgeResponseMapping

PropertyTypeDescription
valuestringPath to extract option value from each response item
labelstringPath or expression for the option label (supports concatenation like "code + ' - ' + description")
descriptionstringPath or expression for hint text shown below the label in dropdowns
autoSelectstringAuto-select a single best-match field from the response
attributesArray<{ 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

  1. The component resolves the bridge slug to an ID via the platform’s /api/resolve endpoint.
  2. It POSTs the params to the bridge proxy endpoint (/api/service-bridges/{id}/proxy/{endpoint}).
  3. If a transform expression is provided, the response is reshaped using JSONata.
  4. The result is injected into a scoped DataContextV2 as ctx.$bridgeResult, along with ctx.$bridgeLoading and ctx.$bridgeError.
  5. 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

PropTypeDefaultDescription
bridgeRefstringrequiredService bridge URI (e.g., "service-bridge://acme/rate-lookup" or "acme/rate-lookup")
endpointstringrequiredEndpoint name defined in the bridge configuration
paramsRecordRequest body sent to the bridge (typically provided via bindings)
transformstringJSONata expression applied to the response before injecting into context

Context Variables

Children of v2:serviceBridgeView receive these additional context variables:
VariableTypeDescription
ctx.$bridgeResultanyThe bridge response (after optional JSONata transform)
ctx.$bridgeLoadingbooleantrue while the request is in flight
ctx.$bridgeErrorstringError 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"

JSONata Transform Reference

The transform prop accepts any valid JSONata expression. Common patterns:
PatternExpressionDescription
Extract a nested arrayresponse.data.itemsDrill into the response structure
Reshape objectsitems.{ "Name": name, "Total": "$" & $string(price * qty) }Create new fields from existing ones
Filter rowsitems[status = "active"]Only include rows matching a condition
Aggregate$sum(items.amount)Compute totals or other aggregations
Sortitems^(>amount)Sort results by a field
String formattingitems.{ "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

FeaturePanel serviceBridge propv2:serviceBridgeView
PurposeMap bridge response to data attributesDisplay bridge response as read-only content
TriggerAttribute path changes (triggerOn)Binding expression changes (reactive params)
Response handlingresponseMapping writes to attributesChildren render from ctx.$bridgeResult
RenderingNo built-in displayChildren render tables, markdown, labels, etc.
Script requiredNoNo
Use caseAuto-populate fields from external dataShow reference data, reports, lookup tables