Skip to content

Moltaro API client

MoltaroApiClient, imported from @moltaro/workspace-ui, is how Workspace UI page code calls this installation’s Moltaro API. It wraps the WebApp’s own HTTP layer: the signed-in user’s bearer token and locale are attached to every request automatically, and responses are unwrapped from the standard ApiResponse envelope. The endpoints you can call are documented in the Runtime API reference.

import { MoltaroApiClient } from '@moltaro/workspace-ui'
const api = new MoltaroApiClient()
export function loadRecord (entityIdOrKey: string, instanceId: string): Promise<unknown> {
return api.requestData<unknown>(
`/api/workspace/entity/${encodeURIComponent(entityIdOrKey)}/instances/${encodeURIComponent(instanceId)}`,
)
}
MethodResolves with
request<T>(path, options?)The full ApiResponse<T> envelope
requestData<T>(path, options?)The Data payload only
requestDataWithWarnings<T>(path, options?){ data: T, warnings: ApiError[] }
requestFormData<T>(path, formData, options?)The Data payload of a multipart upload
requestBlob(path, options?){ blob, contentType, contentDisposition }

The envelope carries Data, Errors, Warnings, and Success. The convenience methods throw ApiClientError — with the HTTP status and the typed errors array — when the response is not successful or carries errors, so page code usually calls requestData and handles one exception type. Error codes and the ApiError shape are described in Error handling.

options is a standard RequestInit: set method and body for writes; Content-Type: application/json is applied automatically when a body is present.

MoltaroApiClient only accepts app-relative Moltaro API paths:

  • The path must start with /api. Absolute URLs, external hosts, protocol-relative // paths, and paths containing \ or # are rejected with a TypeError before any request is sent.
  • Authentication is not configurable: the current user’s bearer token is attached automatically, and passing your own Authorization header is rejected with a TypeError.
  • The active locale is sent automatically, so localized ApiError messages come back in the user’s language.

Requests run as the signed-in user, so the server enforces that user’s permissions on every call. For calls to third-party services, use the External API client instead — it never carries Moltaro credentials.

Five helpers wrap the command and function endpoints so pages can trigger C# business logic without hand-building requests. The full contract — argument shape, statuses, deduplication, and permissions — is documented in Commands and API functions.

invokeCommand runs a published command synchronously and resolves with a WorkspaceUiCommandResult (RunId, optional Message and typed Result):

const abortController = new AbortController()
const result = await api.invokeCommand<{ Total: number }>('recalculate-totals', {
args: { OrderId: orderId },
correlationId: `order-${orderId}`,
signal: abortController.signal,
})

enqueueFunction<TResult> schedules a published API function as a background job and resolves with the initial WorkspaceUiFunctionJobStatus<TResult>:

const job = await api.enqueueFunction<{ ReportId: string }>('rebuild-report', {
args: { Month: month },
deduplicationKey: `rebuild-report-${month}`,
runAfter: '2026-08-01T02:00:00Z',
signal: abortController.signal,
})

The optional runAfter (an ISO-8601 timestamp) delays the job until the given time; omit it to run as soon as a worker is free.

getFunctionJob re-reads a job’s status for polling, and cancelFunctionJob requests cancellation when the status reports CanCancel. Both accept { signal }, and their generic result type controls Run.ResultData:

const status = await api.getFunctionJob<{ ReportId: string }>(job.JobId, {
signal: abortController.signal,
})
if (status.CanCancel) {
await api.cancelFunctionJob(job.JobId, { signal: abortController.signal })
}

waitForFunctionJob performs bounded polling and resolves at Completed, Failed, or Cancelled. It does not treat a failed job as a transport error: inspect both the job Status and Run.Status, then read the typed Run.ResultData only for the successful shape.

import {
WorkspaceUiFunctionJobStatusEnum,
WorkspaceUiFunctionRunStatusEnum,
} from '@moltaro/workspace-ui'
const finalJob = await api.waitForFunctionJob<{ ReportId: string }>(job.JobId, {
pollIntervalMs: 1_000,
timeoutMs: 120_000,
signal: abortController.signal,
})
if (
finalJob.Status === WorkspaceUiFunctionJobStatusEnum.Completed
&& finalJob.Run?.Status === WorkspaceUiFunctionRunStatusEnum.Success
) {
openReport(finalJob.Run.ResultData?.ReportId)
}

WorkspaceUiFunctionJobStatusEnum has the wire values Queued = 0, Leased = 1, Completed = 2, Failed = 3, and Cancelled = 4. WorkspaceUiFunctionRunStatusEnum exposes Success, ValidationFailure, PermissionFailure, Timeout, RuntimeException, Cancelled, Running, Skipped, and StoppedByWorkerRestart with wire values 0 through 8. isFunctionJobTerminal(status) is available when only the job lifecycle matters.

The wait helper defaults to a 60-second timeout and a one-second poll interval. Invalid intervals throw TypeError; an elapsed deadline throws WorkspaceUiFunctionJobWaitTimeoutError with jobId and timeoutMs; aborting the supplied signal stops the active request or delay with the normal browser abort error. API authorization, validation, and network failures retain the usual ApiClientError or browser error semantics.

Command and enqueue options accept an optional correlationId, which is echoed back in results and job statuses so page actions can be traced through run diagnostics.

UI Studio also offers the C# command client and C# background function client source templates. They generate typed .ts modules with cancellation, correlation, deduplication, and bounded job waiting already wired to these SDK helpers. Replace their example argument/result interfaces with the published C# contract used by your project. In the template dialog, Lowercase key controls the generated file and TypeScript type names, while Function key must be the exact published callable key, including dots, underscores, or hyphens when present.

requestBlob fetches binary content from a Moltaro API path and resolves with the Blob plus the response contentType and contentDisposition, so page code can offer downloads with the server-provided file name and type. requestFormData sends a FormData body for uploads and unwraps the JSON envelope like requestData.