The Script API at a Glance
About this page
A script can use a set of ready-made objects, such as plex, email and documents, without importing anything. This page is a map of all of them, grouped by the job they do, with a short example for the ones used most.
It is not the full reference. For every function's parameters, options and return values, open a script and click the book button (Documentation) in the editor's toolbar. The Script Engine Documentation panel opens beside your code, with a Search documentation... box, a Documentation tab with a section for each object below, and a Plex APIs tab for Plex Connect operations. The editor's autocomplete suggests the same names as you type.
Scripts run in a sandboxed JavaScript engine, not Node.js. There is no require or import, no npm packages, and no setTimeout. Every script has a function main(context); see Writing scripts.
Script basics
| Name | What it is for | Main functions |
|---|---|---|
context | The input to the run: what the caller, schedule, webhook, file or email passed in. It is the argument to main. | Read its fields, such as context.orderId. |
console | Write lines to the run's log, shown in the editor and under Executions. | log, info, warn, error, debug |
scripts | Call or reuse another script. | run(name, input) runs it separately and returns its result; include(name) loads it into this run so its functions can be shared; runAsync(name, input) runs it in parallel and returns a Promise. |
What main returns decides what the person or system that ran the script sees: success, script_message, data and, for files, documents. See Writing scripts.
Plex and databases
| Name | What it is for | Main functions |
|---|---|---|
plex | Run a Plex data source, or call the Plex Connect REST API. | plex.execute(options), plex.api.call(options) |
odbc | Read Plex with SQL, preferably a query saved in the SQL Editor. | executeQuery(name, params, opts), executeQueryAsync; execute(sql, params) for one-off SQL |
localdb | Query a PostgreSQL, MySQL or SQL Server database on your own network, through the on-prem connector. Register it under Connectors › Local Databases. | query(connection, sql, params), executeQuery(savedQueryName, params) |
bridge | Call an HTTP API that only exists inside your network, through the on-prem connector. Register it under Connectors › API Bridge. | bridge.fetch(resourceName, path, options) |
Example: run a Plex data source
function main(context) {
const result = plex.execute({
credentialName: "PLEX_BASIC_AUTH",
dataSourceId: "11887",
body: { Workcenter_Code: context.workcenter }
});
if (!result.success) {
return { success: false, script_message: "Plex failed: " + result.error };
}
return { success: true, data: { rows: result.data.rows || [] } };
}
Example: run a saved ODBC query
function main(context) {
try {
const result = odbc.executeQuery("Part Lookup", { part_no: context.partNumber });
return { success: true, data: { rows: result.rows, count: result.rowCount } };
} catch (e) {
// A failed query throws; e.errorCode says why, such as TIMEOUT or SYNTAX.
return { success: false, script_message: "Part Lookup failed: " + e.message };
}
}
Both are covered in detail, with the SQL dialect and limits, in Plex API Access.
Calling other web services
| Name | What it is for | Main functions |
|---|---|---|
fetch | Call any web API that is not Plex: GET, POST, PUT, PATCH, DELETE, with headers, JSON, form or file bodies. Returns { ok, status, headers, body, json(), text() }. | fetch(url, options); fetchAsync(url, options) returns a Promise, for requests in parallel |
http | A short form for a GET, and OAuth 2.0 sign-in. | http.get(url), http.oauthToken(credentialName) |
credentials | Read a secret stored under Script Engine › Credentials, so it never appears in your code. | credentials.get(name) |
Example: call an API with a stored key
function main(context) {
const apiKey = credentials.get("CARRIER_API_KEY");
if (!apiKey) {
return { success: false, script_message: "Credential CARRIER_API_KEY is missing" };
}
const resp = fetch("https://api.carrier.example.com/v1/track/" + encodeURIComponent(context.trackingNo), {
headers: { "Authorization": "Bearer " + apiKey }
});
if (!resp.ok) {
return { success: false, script_message: "Tracking lookup failed: HTTP " + resp.status };
}
return { success: true, data: resp.json() };
}
The host must be on your company's allowed-domains list, and private or local network addresses are always blocked. See Script Credentials & Allowed Domains.
Messages and people
| Name | What it is for | Main functions |
|---|---|---|
email | Send email through your company's email profiles (Admin › Email Configuration), with attachments. | sendWithTemplate(templateName, data, options), send(options) |
approvals | Ask a person or a role for a decision. The request appears in their Approvals inbox (the envelope button in the top bar), and the script you name in onDecision runs when they decide. The requesting script does not wait. | approvals.request(options) |
users | List your company's users and change which roles they have. | list, getRoles, assignRole, removeRole, assignRoles, removeRoles |
roles | Manage your company's roles. | list, get, create, update, delete |
There is no Teams or Slack object for scripts. Workflows have steps for those; see Step reference.
Example: send an email from a template
function main(context) {
const sent = email.sendWithTemplate(
"Order Confirmation",
{ customerName: context.name, orderNumber: context.orderId },
{ to: [context.email] }
);
if (!sent.success) {
return { success: false, script_message: "Email failed: " + sent.error };
}
return { success: true, data: { trackingId: sent.trackingId } };
}
Prefer a saved template over building HTML in the script. Templates are managed under Script Engine › Email Templates (with the Email Management permission), can be changed and test-sent without a new script version, and loop over rows with placeholders such as {{range .rows}}…{{end}}. The script only passes the data and the recipients (to is required). Keep email.send for short plain-text notices. See Email Templates.
Documents, labels and printing
| Name | What it is for | Main functions |
|---|---|---|
documents | Make PDFs and other files from your document templates. | generateSync(template, fields, opts) waits for the file; generate queues it; generateBatch(jobs, opts) makes many at once; mergePdf(parts); getStatus; getTemplateId |
zpl | Turn a ZPL label template and data into ZPL text, without printing. | zpl.fromTemplate(name, data) |
connectors (printing) | Print to label printers on your network, through the on-prem connector. | printFromTemplate(printer, template, data), printBatch, printLabel(printer, zpl), getPrinters, getPrinterStatus, getPrinterHealth |
serial | Take the next number from a serial number pattern. | next(series, ctx), preview, batch(series, count), info, list, register |
Example: make a PDF and return it
function main(context) {
const doc = documents.generateSync(
"Packing Slip",
{ shipper_no: context.shipperNo, lines: context.lines },
{ returnType: "url", timeout: 60000 }
);
if (!doc.success) {
return { success: false, script_message: "Packing slip failed: " + doc.error };
}
return {
success: true,
script_message: "Packing slip ready",
download_url: doc.documentUrl
};
}
To email the file instead, pass doc.documentUrl as an attachment: { url: doc.documentUrl, filename: "Packing-Slip.pdf" }.
Files, EDI and document reading
| Name | What it is for | Main functions |
|---|---|---|
files | Read and write files on an FTP, FTPS or SFTP server or a file share, using the endpoint's name from Connectors › File Exchange. The protocol and login live on the endpoint, not in the script. | list, read, write, delete, move, copy, mkdir, exists |
connectors (files) | Read and write files on a share inside your network through the on-prem connector, by connector ID. | listFiles, readFile, writeFile, moveFile, copyFile, deleteFile, mkdir, fileExists, getConnectors |
edi | Read and write X12 and EDIFACT: parse, validate, map to and from your own objects, acknowledge, and send to a trading partner. | parse, validate, map, buildMapped, ack, process, emit(partner, transactionSet, data) |
ocr | Read a scanned document or image into fields, optionally with a saved extraction profile. Every ocr function returns a Promise, so use async function main and await. | extract, extractProfile, matchProfile, classifyVendor |
See also EDI, Hosted File Gateway and Inbound Email.
Saving data and settings
| Name | What it is for | Main functions |
|---|---|---|
tables | Read and write your User Defined Tables (Extensions › User Defined Tables): mappings, per-customer settings, small lists that change without a script change. A script cannot create a table. | getValue(table, key1, key2), get, exists, set(table, key1, value), list, getAll, clear, listTables |
checkpoint | Remember where a long job got to, so the next run carries on instead of starting over. One checkpoint per script, up to 256 KB. | load(), save(state), clear() |
appSettings | Read and write an Application Designer app's own settings. | get, resolve, all, set, remove, schema, use |
Example: look up and record values in a table
function main(context) {
// Per-customer settings, with a fallback when the customer has no row.
const settings = tables.getValue("customer_settings", context.customerCode);
const template = settings ? settings.template_id : "Standard Invoice";
// Record what happened to this order.
tables.set("order_status", context.orderId, { status: "invoiced", template: template });
return { success: true, data: { template } };
}
Every tables call throws if the table does not exist or is inactive. A missing row is not an error: getValue returns null.
AI
| Name | What it is for | Main functions |
|---|---|---|
ai | Ask a large language model to write, summarise or classify text, or to pull fields out of text or an image into a JSON shape you define. Uses the company's key from the AI Provider Keys page. | ai.complete(promptOrOptions), ai.extract(options) |
When no key is set up, these return { success: false, error } instead of throwing.
Machines and equipment
| Name | What it is for | Main functions |
|---|---|---|
plc | Read and write machine values for a workcenter by role or signal name, as bound under Shop Floor › Settings › Tag Map. | readTag (last known value), read (live), write, readSignal, writeSignal |
assets | The same for plant equipment that is not a Plex workcenter, such as AGVs, conveyors and chargers. | list, readTag, read, write |
Shipping
| Name | What it is for | Main functions |
|---|---|---|
shipping | Rate shopping, carrier labels, LTL freight quotes, tracking and address validation through ShipEngine. Needs a credential named SHIPENGINE. | getRates, createLabel, voidLabel, getLTLQuote, bookLTLQuote, trackShipment, validateAddress, listCarriers |
To run a script around a carrier label that DataMagik makes, see Shipping hooks.
Helpers
The helpers object collects small utilities:
| Job | Functions |
|---|---|
| Safe property access and checks | getOrDefault, deepGet, require, deepClone |
| Text | format, pad, truncate |
| Dates and time zones | now, formatDate, parseDate, dateAdd, dateDiff, startOf, endOf, dateParts |
| Numbers | formatNumber, formatCurrency |
| Reading files | parseCSV, parseExcel, parseXML, toBase64(url) |
| Encoding and signing | base64Encode, base64Decode, hash, hmac, hashEquals, uuid |
| Waiting and retrying | sleep(ms), retry(fn, opts) |
Choosing the right tool
Getting Plex data
| You want to | Use |
|---|---|
| Read many rows, or join several tables, for a report or export | A saved query with odbc.executeQuery |
| Make a change in Plex that a data source does | plex.execute. Find it on Script Engine › Plex Data Sources. |
| Work with customers, sales orders, inventory or other Plex Connect records, or make a change no data source does | plex.api.call. Find the operation on the Documentation panel's Plex APIs tab. |
Reach Plex with fetch | Don't. The Plex helpers handle the address, the login, retries and size limits for you. |
Plex ODBC is read-only: to change Plex data, use a data source or a Plex Connect operation. See Plex API Access.
Sending email
Use email.sendWithTemplate with a saved template for anything with a layout, a table of rows or a standard wording. Use email.send for a one-line, plain-text notice.
Calling an outside service
- A public web API that is not Plex:
fetch, with the key fromcredentials.getand the host on the allowed-domains list. - An API that needs OAuth 2.0: an OAuth 2.0 credential and
http.oauthToken, thenfetch. - Something on your own network:
bridge.fetchorlocaldb, notfetch. Scripts cannot reach private addresses directly.
Keeping data between runs
- Settings and mappings people maintain:
tables, orappSettingsfor an Application Designer app. - How far a long job got:
checkpoint.
Doing several things at once
fetchAsync, odbc.executeQueryAsync and scripts.runAsync return Promises. Use them with await Promise.all([...]) inside an async function main(context) when calls do not depend on each other. The plain versions wait for each call in turn.