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)}`, )}Core request methods
Section titled “Core request methods”| Method | Resolves 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.
Path and header rules
Section titled “Path and header rules”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 aTypeErrorbefore any request is sent. - Authentication is not configurable: the current user’s bearer token is
attached automatically, and passing your own
Authorizationheader is rejected with aTypeError. - The active locale is sent automatically, so localized
ApiErrormessages 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.
Business-logic bridges
Section titled “Business-logic bridges”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.
Files and blobs
Section titled “Files and blobs”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.