Programmable payments

For architects and developers automating payment logic. How PayScript scripts, automations and triggers fit together, and what each lifecycle allows.

When the bank wants payment logic to run

PayScript lets your bank define reusable payment logic and attach it to an automation. A supported trigger determines when the automation runs, for example a schedule, an available-balance crossing or a direct request. Importing a script alone does not start payments.

The business owner defines the intended rule and exceptions. Engineers prepare the approved script, and authorised administrators manage its version and automation settings. Instructions still follow the platform's configured policy, signing and settlement path.

Before relying on a workflow, confirm its supported actions with the service owner and agree how its results will be verified. The current customer API cannot read an automation run's final outcome and sends no run-outcome notification. An active automation or an accepted run is therefore insufficient evidence that a payment succeeded. The configuration and lifecycle details follow below.

From payment logic to an automation

A published script supplies the logic. An active automation selects that version, adds its settings and makes a supported trigger eligible to start work. Keep setup and execution evidence separate.

%%{init: {"theme": "neutral"}}%%
flowchart TB
    Logic["Review the supported payment logic"] --> Publish["Import and publish a script version"]
    Publish --> Bind["Bind the version to an automation"]
    Bind --> Trigger["A supported trigger starts a run"]
    Trigger --> Evidence["Obtain operator evidence of its result"]

Confirm the supported actions and trigger behaviour in your environment. The current customer API cannot read a run's final outcome, and no automation-run notification is sent. Publishing a script or activating an automation does not establish that a payment settled.

View in API Reference

The model

PayScript is Quant Network's language for programmable money, built on Groovy. Banks use it to define payment rules, conditions and automated workflows. Automations can mint, transfer and burn tokens under the conditions a script sets.

ConceptWhat it is
ScriptA YAML document declaring a trigger type, a trigger block, parameters and a code body. Scripts are versioned.
AutomationBinds one published script version to a trigger, with values for the script's parameters. An automation is what runs.
TriggerSets when an automation runs.
RunOne execution of an automation.

Importing a script does not run it. A script runs only once it is published and an automation binds it to a trigger.

All scripts and automations are scoped to your organisation, taken from the access token.

How PayScript fits into a bank integration

Use PayScript when the platform should decide when to request work: at a scheduled time, after an available-balance threshold is crossed, or after an explicit call from your backend. Keep instructions in your bank adapter when the bank needs to control each submission directly.

The script describes reusable logic. The automation selects a published version of that logic and supplies its settings. For example, two scheduled workflows can use the same approved script with different account parameters. Publishing the script makes it available for binding; creating an active automation makes its trigger eligible to fire. Neither action proves that a payment has settled.

PayScript is designed to orchestrate Treasury operations through the platform's existing settlement path. It does not give scripts direct access to signing keys or raw blockchain transactions. The configured policy checks and custody controls still matter for the instructions it produces. Read Operations and their lifecycle and Policy, approvals and audit alongside this guide.

Separate three facts in your application: the script version is published, the automation is active, and a particular run was accepted. A fourth fact, successful execution, needs execution evidence that the public API currently cannot return. Do not display an active automation as proof that all its runs succeeded.

Scripts

A script document has four parts.

PartRequiredContent
triggerTypeYesTIME, BALANCE, TRANSACTION or ON_DEMAND.
triggerPer trigger typeThe trigger's values. ON_DEMAND takes no trigger block.
paramsNoThe settings the code may refer to, each with a key, a type, a label and whether it is required.
codeYesThe code body, in Groovy.

The document is uploaded as a file of up to 50 KB. When it is saved, the structured fields are validated and the code is compiled under a restricted allow-list. The code may use only built-in actions and the parameters the document declares. Any other name is rejected when the script is saved.

The script sandbox

Script code runs in a restricted sandbox. It cannot declare packages, define closures or define new methods, and it can call only an explicit allow-list of methods. A script therefore cannot reach platform or language functions outside that list.

  • Use only actions supported by the imported script and the deployed execution engine. The public API does not publish a complete callable-action catalogue; obtain the approved action names, arguments and effects before writing new script code.
  • Confirm the execution identity and policy path for script-submitted instructions in your environment. A script compiling successfully does not prove it has settlement authority or passes the intended approval gates.

Parameter types are BOOL, INT, DECIMAL, STRING, the _ARRAY form of each, ACCOUNTINFO and BALANCE.

Script lifecycle

StatusMeaning
UNPUBLISHEDImported, not yet usable by automations. Its document can be replaced in place while no automation is linked to it.
PUBLISHEDAutomations can bind to it. Publishing a script also publishes every script it depends on.
OUTDATEDSuperseded by a newer version. Automations already bound to it keep running against it.
DEPRECATEDSuperseded. Automations report it through scriptStatus.
DELETEDSoft-deleted. Reads return 404. Linked automations are disabled.

Replacing the code of a PUBLISHED script creates the next version, UNPUBLISHED, and marks the edited version OUTDATED. Every version shares a rootScriptId, so you can find all automations still running on any version of a script with one call.

Triggers

TriggerFiresTrigger values
ON_DEMANDWhen you call POST /api/automations/{automationId}/executions.None
TIMEAt each occurrence of its schedule.occurrence and occurrenceDetails, for example daily at 09:00 UTC
BALANCEWhen a confirmed Treasury transaction takes an account's available balance across its limit.account, balance (for example < 500), currency
TRANSACTIONAccepted by the script schema.payer and/or payee, optional amount with currency, optional reference

Account fields in a trigger take the keywords OWNER, any, anyExcept(a, b), or a concrete account identifier.

  • Validate each trigger you use in the assigned environment. Schema acceptance of TRANSACTION does not by itself establish that the trigger is executed.
  • Test the documented available-balance crossing after a confirmed operation; a pending instruction or the account remaining below the threshold does not establish a new crossing.

Understand a balance crossing

The PayScript integration guide specifies available balance, evaluated when a confirmed Treasury transaction takes the watched account across its configured limit. It is event-driven, rather than a promise to poll the account continuously.

For a condition below 500.00 GBP, a confirmed payment that changes available balance from 600.00 to 450.00 crosses the limit. The account simply remaining at 450.00 is not another crossing. A pending payment does not establish the confirmed balance change. Test the crossing in your assigned environment with an approved script and obtain execution evidence before relying on the automation.

For scheduled runs, configure the required timeZone as well as the occurrence details. Keep the schedule's time zone separate from response timestamps, which are UTC. For direct runs, use an ON_DEMAND script and the execution endpoint.

Automations

An automation binds a PUBLISHED script to a trigger. Its triggerType must match the one the script declares, and its parameter values must fit the script's declared parameters. It is created ACTIVE and owned by the user who created it.

StatusMeaningAllowed transitions
ACTIVECan fire.to INACTIVE
INACTIVEPaused.to ACTIVE, or to DISABLED
DISABLEDPermanently stopped. Terminal.none
DELETEDSoft-deleted through DELETE. Still listed, keeps its history, cannot run.none

Every creation and status change is recorded in the automation's history, with who made it and when.

An ON_DEMAND automation can be run by anyone in the organisation. A run can override the automation's parameter values for that run only. Overrides are never written back.

Runs

Requesting a run returns 202 with an executionId. The acknowledgement is not a run record.

The API does not expose run records or run outcomes. There is no endpoint to read whether a run succeeded, what it did, or why a trigger did or did not fire. No webhook event is sent for automation runs. Keep your own execution-request record and obtain operator evidence when a run outcome is needed. A 202 is acceptance and cannot be reported to users as successful execution.

Correlate observed transactions with your own business instruction and operator-supplied execution evidence. The public API does not promise a run-to-transaction correlation field.

The executionId is derived from the Idempotency-Key and the automation id. Retrying with the same key replays the first 202 with Idempotency-Replayed: true and does not start a second run.

Change a payment workflow without losing version history

Before replacing a published script, list its versions using any version's script ID, and list its automations using the lineage's rootScriptId filter. A new script version does not migrate existing automations: they retain the version they were bound to, even when it is OUTDATED.

Publish the replacement script and prepare its reviewed parameters. Plan the handover so both versions do not issue the same business instruction: creating an automation makes it ACTIVE immediately, so pause the old automation before creating the replacement. This handover can introduce a gap; account for scheduled occurrences and any already accepted runs with the operator. After verifying the handover, permanently disable the old automation if it is no longer needed. Retain the script version, automation ID and execution request in your evidence records.

Deprecation applies to an OUTDATED script version. It is refused while automations on that version remain ACTIVE; remaining automations are disabled when deprecation succeeds. It is terminal. Use Write and run an automation for the actual requests and script recipes for download, clone and version-history examples.

Worked example

Run an ON_DEMAND automation, overriding one parameter for this run.

POST /api/automations/c33d1f7a-9e21-4b8c-a6d2-0f3b7c9e5a44/executions HTTP/1.1
Host: api.qfp.quantnetwork.net
Authorization: Bearer <access token>
API-Version: 1.0.0
Content-Type: application/json
Idempotency-Key: 2b6d9f14-7c3e-4a58-b1d0-9e5f3a7c2d86

{
  "parameterOverrides": [
    { "key": "savingsAccount", "value": "acc_777", "type": "STRING" }
  ]
}
HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "executionId": "5f2c8a1e-3b4d-5e6f-9a0b-1c2d3e4f5061",
  "automationId": "c33d1f7a-9e21-4b8c-a6d2-0f3b7c9e5a44",
  "createdAt": "2026-08-18T11:26:46.312Z",
  "parameters": [
    { "key": "savingsAccount", "value": "acc_777", "type": "STRING" }
  ]
}

PayScript timestamps are ISO 8601 UTC instants with fixed millisecond precision, for example 2026-08-18T11:26:46.312Z.

A script document looks like this (from the API Reference):

triggerType: BALANCE
trigger:
  account: OWNER
  balance: < 500
  currency: GBP
params:
  - key: topUpTo
    type: DECIMAL
    required: true
    label: Top up to
code: |
  logMessage("Balance fell below the limit; topping up to " + topUpTo.toString());

The source example uses OWNER; treat it as an example to validate against the deployed engine rather than a substitute for checking the imported script's trigger rules.

View in API Reference

Errors and edge cases

SituationResponse
Script fails validation or compilation, or its name is already used400, naming the field or compilation error
Creating an automation from a script that is not PUBLISHED409
Running an automation that is not ACTIVE or not ON_DEMAND409
A run override with an unknown key, or a value that does not parse as its type422
Missing Idempotency-Key on a run request400
An earlier request with the same Idempotency-Key still in progress409
A disallowed automation status transition, including to its current status400
Deleting a PUBLISHED script, or one with ACTIVE automations or dependants409

API Reference

Open an endpoint for request fields, response examples and the interactive API console.

Related pages

Implementation resources

Scripts code recipes.

Use Implement a backend client for request handling, durable idempotency and outcome tracking. The developer integration coverage map links every public operation to its API Reference and contract-derived code recipe. Replace example identifiers with values from your assigned environment.


Did this page help you?