Skip to content

Workflow SDK 1.0.0

This page is the API reference of @acriva/workflow-sdk 1.0.0, the SDK you write scripts in the workflow designer against. It is generated from the SDK’s declarations and doesn’t change once the version is released. How to write, test and publish a script is in the guide Customize and program workflows; what changed in each version is in the changelog.

SDK 1.x grows only additively: new hooks, ctx members, helpers and optional parameters are added, nothing is taken away. Unions a script receives (Hook, TaskOutcome, the keys of the workspace’s types) may therefore gain members; a switch over one needs a default branch.

A reference to another object of the workspace, such as a contact in a “vendor” field.

Property Modifier Type Description
id readonly string The object’s ID.
name readonly string The object’s display name.

The fields a script reads as ctx.document.fields: its step’s inputs, key → type. Empty in the SDK; the workspace’s types (tenant.d.ts, GET /workflows/sdk/types) add to it through module augmentation. A required field has its type, an optional one type | null. Types: string (text), number, Money, PlainDate, boolean, a union of the option keys (enumeration) and Reference.

tenant.d.ts
import type { Money, Reference } from '@acriva/workflow-sdk';
declare module '@acriva/workflow-sdk' {
interface DocumentFields {
bruttobetrag: Money;
lieferant: Reference;
kostenstelle: string | null;
}
}

The fields a script may set with EffectContext.setField, key → type: the fields of the trigger’s document type without those Finance reads for an invoice, and the fields the workflow declares. Empty in the SDK; tenant.d.ts adds to it as it does to DocumentFields.


The workspace’s document types: one entry per key (eingangsrechnung: true). Empty in the SDK; tenant.d.ts adds to it. Without entries, DocumentTypeKey is string.


The workspace’s file types: one entry per key. Empty in the SDK; tenant.d.ts adds to it. Without entries, FileTypeKey is string.


The workspace’s tags: one entry per name ('über 500 €': true). Empty in the SDK; tenant.d.ts adds to it. Without entries, TagName is string.


The workspace’s roles: one entry per role, a built-in role by its key (admin), a custom role by its name. Empty in the SDK; tenant.d.ts adds to it. Without entries, RoleKey is string.


The workspace’s cost centers: one entry per number ('4200': true), the active ones from Finance. Empty in the SDK; tenant.d.ts adds to it. Without entries, CostCenterNumber is string.


The fields of every document type: the type’s key → (the field’s key → type), as for DocumentFields. Empty in the SDK; tenant.d.ts adds to it. FieldsOf reads one type from it.


The fields of every document type that a script may set: the type’s key → a union of the keys (without those Finance reads for an invoice). Empty in the SDK; tenant.d.ts adds to it. SettableFieldsOf reads one type from it.


A file the document lies in.

Property Modifier Type Description
type readonly FileTypeKey The file type’s key.
number readonly string The file’s number.

The document the workflow runs for: its metadata, never its text.

Property Modifier Type Description
id readonly string The document’s ID.
type readonly DocumentTypeKey The key of its document type.
fields readonly Readonly<DocumentFields> The fields the step declares as inputs, typed from tenant.d.ts (DocumentFields).
tags readonly readonly TagName[] The names of its tags.
files readonly readonly FileRef[] The files it lies in.

The workflow instance the script runs in.

Property Modifier Type Description
id readonly string The instance’s ID.
step readonly string The script step’s name.
lastTaskOutcome readonly TaskOutcome | null The outcome of the instance’s last completed task, null before the first.

What run returns: the result of EffectContext.branch or EffectContext.result. Only the SDK creates it.

Type Parameter
O extends Outputs
Property Modifier Type
[resultBrand] readonly O

A notice of EffectContext.notify.

Property Modifier Type Description
to readonly readonly Recipient[] The recipients.
text readonly string Plain text, at most 1,000 characters. A recipient who can’t read the document gets a link only.

What every script gets in run, on every hook. ctx is frozen; the clock and randomness exist only here, because Date.now and Math.random are missing in a script.

Property Modifier Type Description
document readonly ScriptDocument The document the workflow runs for.
instance readonly ScriptInstance The workflow instance.
sources readonly Sources The workspace’s data sources, read-only (Sources): external JSON endpoints an admin configured.
tables readonly Tables The workspace’s data tables, read-only (Tables): reference data such as a vendor list.
now(): Date;

The run’s point in time; the same throughout one run.

Date

today(): PlainDate;

Today’s date in Germany (Europe/Berlin), at the run’s point in time.

PlainDate

random(): number;

A random number in [0, 1), in place of Math.random.

number

log(...values): void;

Writes a line to the run’s console (at most 1,000 characters per line, 1,000 lines per run).

Parameter Type Description
…values readonly unknown[] The line’s values, separated by spaces.

void

hint(text): void;

Attaches a note to the instance’s next task (plain text, at most 500 characters, marked as the script’s output). The only effect on beforeApproval.

Parameter Type Description
text string The note.

void


ctx on the hooks with effects (onDocumentArrived, onApproved, onRejected, onTimer). Effects are collected and only checked and applied as the instance after the run; a test run applies nothing.

Type Parameter Default type
O extends Outputs Outputs
Property Modifier Type Description Inherited from
document readonly ScriptDocument The document the workflow runs for. ScriptContext.document
instance readonly ScriptInstance The workflow instance. ScriptContext.instance
sources readonly Sources The workspace’s data sources, read-only (Sources): external JSON endpoints an admin configured. ScriptContext.sources
tables readonly Tables The workspace’s data tables, read-only (Tables): reference data such as a vendor list. ScriptContext.tables
now(): Date;

The run’s point in time; the same throughout one run.

Date

ScriptContext.now

today(): PlainDate;

Today’s date in Germany (Europe/Berlin), at the run’s point in time.

PlainDate

ScriptContext.today

random(): number;

A random number in [0, 1), in place of Math.random.

number

ScriptContext.random

log(...values): void;

Writes a line to the run’s console (at most 1,000 characters per line, 1,000 lines per run).

Parameter Type Description
…values readonly unknown[] The line’s values, separated by spaces.

void

ScriptContext.log

hint(text): void;

Attaches a note to the instance’s next task (plain text, at most 500 characters, marked as the script’s output). The only effect on beforeApproval.

Parameter Type Description
text string The note.

void

ScriptContext.hint

setField<K>(key, value): void;

Sets a field of the document; null clears it. After an approval (onApproved, an onTimer after it) only an empty field the workflow declares.

Type Parameter
K extends keyof SettableFields & string
Parameter Type Description
key K The field’s key.
value | FieldInput<NonNullable<SettableFields[K]>> | null The new value.

void

addTag(name): void;

Adds an existing tag to the document.

Parameter Type Description
name TagName The tag’s name.

void

fileInto(file): void;

Files the document into a file.

Parameter Type Description
file FileRef The file’s file type and number.

void

notify(notice): void;

Notifies members or roles of the workspace.

Parameter Type Description
notice Notice Recipients and text.

void

branch(value, values?): ScriptResult<O>;

Picks the step’s exit: one of the fixed values from outputs. Return the result from run.

Parameter Type Description
value BranchValue<O> The exit’s value.
values? OutputValues<O> Further return values.

ScriptResult<O>

The result for run.

result(values): ScriptResult<O>;

Returns return values without an exit; the step then goes to its default next step.

Parameter Type Description
values OutputValues<O> The return values.

ScriptResult<O>

The result for run.


The hooks: where a script step sits in the workflow, and which ctx it gets.

Type Parameter Default type
O extends Outputs Outputs
Property Type Description
onDocumentArrived EffectContext<O> As soon as a document has arrived and been recognized, before the first step. All effects.
beforeApproval ScriptContext Before an approval or review, read-only: the only effect is ScriptContext.hint on that task.
onApproved EffectContext<O> After an approval. All effects; fields only when they are empty and declared.
onRejected EffectContext<O> After a rejection. All effects.
onTimer EffectContext<O> After a deadline or a schedule. All effects; after an approval, fields only when they are empty and declared.

A script on a hook with effects.

Type Parameter
O extends Outputs
Property Modifier Type Description
hook readonly EffectHook The hook; it must be the step’s.
outputs? readonly O The script’s return values.
run(ctx): MaybePromise<void | ScriptResult<O>>;

The script’s code. Without a result, the step goes to its default next step.

Parameter Type Description
ctx EffectContext<O> The document, the instance and the effects.

MaybePromise<void | ScriptResult<O>>


A script on beforeApproval: read-only, without return values.

Property Modifier Type Description
hook readonly "beforeApproval" The hook.
run(ctx): MaybePromise<void>;

The script’s code.

Parameter Type Description
ctx ScriptContext The document and the instance, read-only, and ctx.hint.

MaybePromise<void>


A defined script, the file’s default export. Only the SDK creates it.

Type Parameter
O extends Outputs
Property Modifier Type
[scriptBrand] readonly O

Amounts of money in German notation.

format(value): string;

Formats an amount: 1249.5 → '1.249,50 €'.

Parameter Type Description
value number The amount in euros.

string

parse(text): Money | null;

Reads an amount in German notation, with or without thousands separators and €: '1.249,50 €' → 1249.5. null when the text isn’t an amount.

Parameter Type Description
text string The text.

Money | null

round(value): Money;

Rounds half away from zero to cents: 12.345 → 12.35.

Parameter Type Description
value number The amount.

Money


Calendar days (PlainDate) in German notation.

format(value): string;

Formats a day as DD.MM.YYYY: '2026-10-14' → '14.10.2026'. A Date counts in Europe/Berlin.

Parameter Type Description
value PlainDate | Date The day.

string

parse(text): PlainDate | null;

Reads a day as DD.MM.YYYY or YYYY-MM-DD. null when the text isn’t a valid day.

Parameter Type Description
text string The text.

PlainDate | null

addDays(value, days): PlainDate;

Adds calendar days; negative ones subtract.

Parameter Type Description
value PlainDate The day.
days number The number of days.

PlainDate

daysBetween(from, to): number;

The calendar days from from to to, negative when to is earlier.

Parameter Type Description
from PlainDate The first day.
to PlainDate The second day.

number


The workspace’s data sources: key → { params; response }, the query parameters the source takes and the JSON type of its answer. Empty in the SDK; tenant.d.ts adds to it. Without entries, DataSourceKey is string, the parameters are free and the answer is unknown.

tenant.d.ts
declare module '@acriva/workflow-sdk' {
interface DataSourceRegistry {
erp: { params: { lieferantId: string }; response: { kostenstelle: string; kreditor: string } };
}
}

The workspace’s data tables: key → { key; row }, the type of the table’s key and its row (column key → type). Empty in the SDK; tenant.d.ts adds to it. Without entries, DataTableKey is string.

tenant.d.ts
declare module '@acriva/workflow-sdk' {
interface DataTableRegistry {
lieferanten: { key: string; row: { lieferantId: string; name: string; kostenstelle: string } };
}
}

A request to a data source for Sources.get.

Type Parameter
K extends DataSourceKey
Property Modifier Type Description
path? readonly string A path relative to the source’s base URL ('lieferanten/4711'). The broker encodes every segment, so .., //, @ and a backslash can’t leave the base path or change the host.
query? readonly SourceParams<K> The query parameters; the broker encodes them.

ctx.sources: reads external data through the platform’s broker. The script itself has no network.

A step must declare the source among its inputs (an input of kind Source), otherwise the call answers 'not-declared'. At most 10 calls and 30 s of broker time per run, then 'limit'; a cache hit counts as a call. GET only.

get<K>(key, request?): Promise<SourceResult<SourceResponse<K>>>;

Calls the data source key.

Type Parameter
K extends DataSourceKey
Parameter Type Description
key K The source’s key.
request? SourceRequest<K> The path and the query parameters.

Promise<SourceResult<SourceResponse<K>>>

The data, or the reason there is none.


ctx.tables: reads rows of the workspace’s data tables through the platform’s broker.

A step must declare the table among its inputs (an input of kind Table); the check reports an undeclared table before publishing. At most 50 lookups per run, lookup and query together. Unlike Sources, a refusal here is no result: a table the step doesn’t declare (table-not-declared) or the 51st lookup (limit-table-lookups) ends the run with that code, as an exceeded limit does, and a catch doesn’t stop it. A silent null would read as “not in the list” and could route a document the wrong way (a blocklist check, say).

lookup<K>(table, key): Promise<TableRow<K> | null>;

The row whose key is key, or null when there is none.

Type Parameter
K extends DataTableKey
Parameter Type Description
table K The table’s key.
key TableKeyOf<K> The row’s key; its canonical text form is compared.

Promise<TableRow<K> | null>

The row or null.

query<K>(table, filter): Promise<readonly TableRow<K>[]>;

The rows whose columns equal the filter: at most 100, ordered by key, so the cap returns the same rows every time.

Type Parameter
K extends DataTableKey
Parameter Type Description
table K The table’s key.
filter TableFilter<K> Equality on 1 to 3 columns.

Promise<readonly TableRow<K>[]>

The rows, perhaps none.

type Money = number & object;

An amount of money in euros, as a number with at most two decimals. It compares and computes like a number (amount > 500); the result of a computation is a number.

readonly [moneyBrand]: "EUR";

type PlainDate = string & object;

A calendar day without time and time zone, as ISO text YYYY-MM-DD ('2026-10-14'). Two days compare with < and >. Create one with date or ScriptContext.today.

readonly [plainDateBrand]: "PlainDate";

type FieldsOf<T> = T extends keyof DocumentTypeFieldsRegistry ? DocumentTypeFieldsRegistry[T] : object;

The fields of document type T, key → type; {} for a type without fields. The editor and the check derive a step’s DocumentFields from it (interface DocumentFields extends Pick<FieldsOf<'…'>, '…'> {}).

Type Parameter
T extends DocumentTypeKey

type SettableFieldsOf<T> = Pick<FieldsOf<T>, Extract<T extends keyof SettableFieldKeysRegistry ? SettableFieldKeysRegistry[T] : never, keyof FieldsOf<T>>>;

The fields of document type T that a script may set, key → type; the base of SettableFields.

Type Parameter
T extends DocumentTypeKey

type RegistryKey<R> = [keyof R] extends [never] ? string : Extract<keyof R, string>;

A registry’s keys, or string while it is empty.

Type Parameter
R

type DocumentTypeKey = RegistryKey<DocumentTypeRegistry>;

A document type’s key.


type FileTypeKey = RegistryKey<FileTypeRegistry>;

A file type’s key.


type TagName = RegistryKey<TagRegistry>;

A tag’s name.


type RoleKey = RegistryKey<RoleRegistry>;

A role’s key.


type CostCenterNumber = RegistryKey<CostCenterRegistry>;

A cost center’s number.


type FieldInput<T> = T extends Money ? number : T extends Reference ? Pick<Reference, "id"> : T;

The value EffectContext.setField takes for a field of type T: a number for Money, the ID for Reference, otherwise T.

Type Parameter
T

type TaskOutcome = "Approved" | "Rejected" | "Returned" | "Done";

The outcome of a completed task. The union may gain values in 1.x.


type OutputType =
| readonly [string, ...string[]]
| "text"
| "number"
| "money"
| "date"
| "boolean"
| "reference";

The type of a return value in outputs: a list of fixed values (an enumeration the step can branch on) or the name of a type.


type Outputs = object;

A script’s return values: key (camelCase, at most 40 characters) → OutputType. Later conditions read them; an enumeration’s values are the step’s exits.

[key: string]: OutputType

type OutputValue<T> = T extends readonly string[] ? T[number] : T extends "text" ? string : T extends "number" | "money" ? number : T extends "date" ? PlainDate : T extends "boolean" ? boolean : T extends "reference" ? Pick<Reference, "id"> : never;

The value of a return value of type T.

Type Parameter
T extends OutputType

type BranchValue<O> = { [K in keyof O]: O[K] extends readonly string[] ? O[K][number] : never }[keyof O];

The values a script can branch on: all fixed values of its enumeration return values.

Type Parameter
O extends Outputs

type OutputValues<O> = { readonly [K in keyof O]?: OutputValue<O[K]> | null };

Return values with their values; each is optional, null means “no value”.

Type Parameter
O extends Outputs

type Recipient =
| {
member: string;
role?: never;
}
| {
role: RoleKey;
member?: never;
};

A recipient of EffectContext.notify: a member of the workspace by email address or a role by key, never a free address.


type Hook = keyof HookContexts;

A hook’s name. The union may gain hooks in 1.x (onExport comes later).


type EffectHook = Exclude<Hook, "beforeApproval">;

The hooks with effects.


type MaybePromise<T> = T | Promise<T>;

A value or a promise of it.

Type Parameter
T

type ScriptDefinition<O> =
| EffectScriptDefinition<O>
| ReadOnlyScriptDefinition;

A script’s description for defineScript; hook decides which ctx run gets.

Type Parameter
O extends Outputs

type DataSourceKey = RegistryKey<DataSourceRegistry>;

A data source’s key.


type DataTableKey = RegistryKey<DataTableRegistry>;

A data table’s key.


type SourceParamValue = string | number | boolean;

A query parameter’s value; the broker encodes it.


type SourceParams<K> = K extends keyof DataSourceRegistry ? DataSourceRegistry[K] extends object ? { readonly [N in keyof P]: P[N] & SourceParamValue } : never : object;

The query parameters of the data source K, from DataSourceRegistry.

Type Parameter
K extends DataSourceKey

type SourceResponse<K> = K extends keyof DataSourceRegistry ? DataSourceRegistry[K] extends object ? R : unknown : unknown;

The JSON type of the answer of the data source K, from DataSourceRegistry; unknown without an entry.

Type Parameter
K extends DataSourceKey

type SourceError =
| "data-source-blocked"
| "timeout"
| "too-large"
| "invalid-response"
| "http-error"
| "not-declared"
| "confidential"
| "limit";

Why a call of a data source returns no data. The union may gain values in 1.x.

  • 'data-source-blocked': the guard against internal addresses refused the address.
  • 'timeout': the source didn’t answer within its timeout.
  • 'too-large': the answer is larger than 1 MiB.
  • 'invalid-response': the answer isn’t JSON, or it fails the source’s schema.
  • 'http-error': the source answered with a status outside 2xx (see status).
  • 'not-declared': the step doesn’t declare the source among its inputs.
  • 'confidential': the document is confidential, and the source doesn’t allow confidential documents.
  • 'limit': the run has used its 10 calls (or 30 s of broker time).

type SourceResult<T> =
| {
ok: true;
status: number;
data: T;
cached: boolean;
}
| {
ok: false;
error: SourceError;
status?: number;
};

The result of Sources.get: data when ok: true, otherwise a SourceError. A refusal is a result, never an exception; check ok before you read data.

Type Parameter
T
{
ok: true;
status: number;
data: T;
cached: boolean;
}
readonly ok: true;

The source answered.

readonly status: number;

The HTTP status (2xx).

readonly data: T;

The answer as JSON.

readonly cached: boolean;

true when the answer comes from the source’s cache; that counts as a call too.


{
ok: false;
error: SourceError;
status?: number;
}
readonly ok: false;

The call returned no data.

readonly error: SourceError;

The reason.

readonly optional status?: number;

The HTTP status when the source answered ('http-error').


type TableCellValue = string | number | boolean | null;

The value of a data table’s cell without an entry in DataTableRegistry: text, number, amount, date (ISO text), boolean or null.


type TableRow<K> = K extends keyof DataTableRegistry ? DataTableRegistry[K] extends object ? Readonly<R> : never : object;

A row of the data table K, column key → value, the key column included.

Type Parameter
K extends DataTableKey

type TableKeyOf<K> = K extends keyof DataTableRegistry ? DataTableRegistry[K] extends object ? Key : never : string | number;

The type of the data table K’s key. The broker compares the canonical text form: text trimmed and NFC-normalised, a number as a canonical decimal, a date as ISO text ('2026-10-14').

Type Parameter
K extends DataTableKey

type TableFilter<K> = Partial<TableRow<K>>;

A filter for Tables.query: equality on at most 3 columns of the row. The broker refuses more columns, or none.

Type Parameter
K extends DataTableKey
const moneyBrand: unique symbol;

const plainDateBrand: unique symbol;

const resultBrand: unique symbol;

const scriptBrand: unique symbol;

const money: MoneyHelpers;

The helpers for amounts of money.


const date: DateHelpers;

The helpers for calendar days.

function defineScript<O>(script): Script<O>;

Defines a script. Every script file default-exports exactly one defineScript(…) and imports nothing but '@acriva/workflow-sdk'.

Type Parameter Default type
O extends Outputs object
Parameter Type Description
script ScriptDefinition<O> The hook, the return values and the code.

Script<O>

The script for the default export.

import { defineScript } from '@acriva/workflow-sdk';
export default defineScript({
hook: 'onDocumentArrived',
outputs: { weg: ['gf', 'kostenstelle'] },
async run(ctx) {
return ctx.branch(ctx.document.fields.bruttobetrag > 500 ? 'gf' : 'kostenstelle');
},
});