Developer Portal for YouTrack and Hub Help

Asynchronous Functions

Most calls to the YouTrack Workflow API run synchronously. The script receives the result and continues in the same script execution while the current operation is still being processed. In workflow rules, this synchronous work belongs to the current workflow transaction. To learn how YouTrack processes workflow rule changes in transactions, see Transactions.

Async functions introduce a separate follow-up step. An asynchronous function is a named JavaScript function declared in an asyncFunctions object. The script schedules it by name with the ctx.invokeAsync() method or an async HTTP method, and YouTrack runs it after the current transaction is complete.

Use async functions for tasks that should not block the operation that starts them. Common use cases include sending a request to an external service, handling the response later, delaying an update, and debouncing repeated changes.

Async functions are supported in on-change, action, and on-schedule workflow rules, app HTTP handlers, and custom MCP tools. The examples in this article use workflow rules, but the core pattern is the same in every supported script type.

Rule Sample

The following workflow rule saves the old and new issue summaries, then schedules an async function that adds a comment two seconds later:

const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Comment on summary changes later', guard: (ctx) => ctx.issue.isChanged('summary'), action: (ctx) => { // Save values that the async function needs later. ctx.store('previousSummary', ctx.issue.oldValue('summary') || ''); ctx.store('updatedSummary', ctx.issue.summary); // Schedule the async function to run two seconds later. ctx.invokeAsync('addSummaryChangeComment', 2000); }, asyncFunctions: { addSummaryChangeComment: (ctx) => { // Load values from the async execution context. const previousSummary = ctx.load('previousSummary'); const updatedSummary = ctx.load('updatedSummary'); ctx.issue.addComment( 'Summary changed from "' + previousSummary + '" to "' + updatedSummary + '".' ); } } });

Concepts and Scope

Async functions use the same scheduling pattern across supported script types. The available context, execution timing, limits, and related objects and methods depend on where the async work starts.

Supported Script Types

You can use async functions in the following script types:

Script type

Notes

On-change, action, and on-schedule workflow rules

Async functions use the same workflow rule context as the rule action, including ctx.issue, ctx.currentUser, and rule requirements.

App HTTP handlers

Async functions can be scheduled from app HTTP handler endpoints with issue, project, article, user, or global scope. For details about handling responses from async HTTP calls, see Call External Services after Transaction Completion.

Custom MCP tools

Async functions can be scheduled from the custom MCP tool action. The async function context follows the custom MCP tool context, so it provides ctx.arguments but not ctx.issue, ctx.article, or ctx.user.

Async Execution Flow

After a script schedules async work, YouTrack runs the follow-up function as a separate step:

  • The scheduling function calls the ctx.invokeAsync() method or an async HTTP method with the name of an async function.

  • If the transaction is completed successfully, YouTrack starts the follow-up work later as the same user.

  • The follow-up function receives a new ctx object based on the script type that scheduled the work.

  • When the follow-up function needs values from the scheduling function, the scheduling function stores them with ctx.store(), and the follow-up function reads them with ctx.load().

Objects and Methods for Async Work

Async functions interact with different objects and methods depending on the task. A script can schedule a named async function with the ctx.invokeAsync() method. For async HTTP calls, the script also uses HTTP module methods and the async HTTP response context.

Script Object

The asyncFunctions object declares named async functions in the same script object that schedules them.

For more information, see Declare and Schedule an Async Function.

Context Methods

The ctx object provides methods for scheduling an async function and passing short-lived state between async steps.

HTTP Module Methods

The @jetbrains/youtrack-scripting-api/http module provides async HTTP methods for sending an HTTP request later.

postAsync(), getAsync(), and other async HTTP methods pass the external service response to a named async function. For more information, see Call External Services after Transaction Completion.

Async HTTP Response Context

The ctx.response property contains the external service response in the async function passed to an async HTTP method.

For more information, see Call External Services after Transaction Completion.

Work with Async Functions

Async follow-up work depends on two things: the function YouTrack should run later and the values that should be available when that function runs.

Declare and Schedule an Async Function

Declare async functions in an asyncFunctions object in the same script object that starts the work. The asyncFunctions object is a top-level property of the script object. Depending on the script type, place it next to properties such as action, handle, or execute.

The asyncFunctions object is a map of function names to JavaScript functions. Pass one of these names to the ctx.invokeAsync() method or to an async HTTP method. Inline callbacks are not supported.

The ctx.invokeAsync() method schedules a named async function for execution after the current transaction is complete. It doesn't return a value from the async function.

The ctx.invokeAsync() method accepts the following parameters:

Parameter

Description

Required

functionName

A string that matches a key in the asyncFunctions object.

delay

The delay before async execution, in milliseconds.

Default value: 0.

deduplicationKey

A string key that lets YouTrack replace a pending async call with a newer one.

Use it when repeated scheduling should collapse pending calls, for example to debounce frequent updates to the same issue.

When another pending call with the same key exists for the same script configuration, YouTrack deletes the old call and schedules the new one with a fresh delay. In workflow rules, the deduplication scope is a specific rule attached to a specific project. The same key in another rule or another project doesn't replace the pending call.

Share State Across Async Calls

Stored values are short-lived data for follow-up work. They are scoped to one async call chain and are cleaned up when the chain is complete. For long-lived data, use app settings or YouTrack entities.

The following methods save and read stored values:

ctx.store(key, value)

The ctx.store() method saves a value in the async execution context before the script schedules an async function or async HTTP call.

Stored values are persisted only when the same script execution also schedules an async function or an async HTTP call.

Example:

// Save a value for the async function. ctx.store('commentText', 'Summary changed to: ' + ctx.issue.summary); ctx.invokeAsync('addSummaryComment');

Parameter

Description

key

A string identifier for the stored value.

value

A primitive value, null, or a reference to a YouTrack entity.

ctx.load(key)

The ctx.load() method reads a value saved with ctx.store() inside an async function. It returns null when the specified key has not been stored.

Stored entity references are resolved back to YouTrack entity objects.

Example:

// Read a value saved in the scheduling function. const commentText = ctx.load('commentText');

Parameter

Description

key

A string identifier for the stored value to load.

Async HTTP Calls and Chaining

Async HTTP methods let a script schedule an HTTP request that YouTrack sends only after the transaction is complete. Async functions can also schedule another step, which lets scripts run ordered follow-up work without blocking the operation that started it.

Call External Services after Transaction Completion

The @jetbrains/youtrack-scripting-api/http module provides async variants of HTTP request methods: doAsync, getAsync, postAsync, putAsync, patchAsync, and deleteAsync.

These async HTTP methods schedule the outgoing HTTP request during the current script execution. YouTrack sends the request after the current transaction is complete. Pass the name of an async function as the last argument. When YouTrack receives the external service response, it invokes that function and exposes the response as the ctx.response property.

Async HTTP methods don't return the response to the scheduling function and don't support delayed execution. Put the external response handling logic in the named async function.

The following workflow rule sends an HTTP request and handles the response in an async function:

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const http = require('@jetbrains/youtrack-scripting-api/http'); exports.rule = entities.Issue.onChange({ title: 'Notify external service after transaction completion', guard: (ctx) => ctx.issue.isChanged('State'), action: (ctx) => { const connection = new http.Connection('https://api.example.com'); connection.addHeader('Content-Type', 'application/json'); // Schedule YouTrack to send the HTTP request after this transaction is complete. connection.postAsync( '/issue-events', null, JSON.stringify({id: ctx.issue.id, state: ctx.issue.fields.State.name}), 'onExternalResponse' ); }, asyncFunctions: { onExternalResponse: (ctx) => { // The ctx.response property contains the external service response. if (ctx.response.isSuccess) { ctx.issue.addComment('External service accepted the update.'); } else { console.warn('External service failed: ' + ctx.response.body); } } } });

For more details about HTTP requests in workflow rules, see Using REST API Methods in JavaScript Workflows.

Chain Async Calls

An async function can schedule the next async step. Use chained async calls when follow-up work has to happen in sequence, for example when one async function prepares data and the next one sends it to an external service.

Each script function execution can schedule only one async function or one async HTTP call. The default maximum chain length is 10 async executions.

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const http = require('@jetbrains/youtrack-scripting-api/http'); exports.rule = entities.Issue.onChange({ title: 'Send issue update in async steps', guard: (ctx) => ctx.issue.isChanged('State'), action: (ctx) => { const state = ctx.issue.fields.State ? ctx.issue.fields.State.name : ''; // Schedule the first async step for after this transaction is complete. ctx.store('stateName', state); ctx.invokeAsync('preparePayload'); }, asyncFunctions: { preparePayload: (ctx) => { // This async function can schedule the next step in the chain. const payload = JSON.stringify({ issueId: ctx.issue.id, state: ctx.load('stateName') }); ctx.store('payload', payload); ctx.invokeAsync('sendPayload'); }, sendPayload: (ctx) => { const connection = new http.Connection('https://api.example.com'); connection.addHeader('Content-Type', 'application/json'); // The async HTTP response handler is the next step in the same chain. connection.postAsync('/issue-events', null, ctx.load('payload'), 'onServiceResponse'); }, onServiceResponse: (ctx) => { // This async response handler runs when YouTrack receives the external response. if (!ctx.response.isSuccess) { console.warn('External service failed: ' + ctx.response.body); } } } });

Execution Behavior and Limits

Async functions are delayed follow-up executions with limits that affect how work can be scheduled and chained. These limits apply to every supported script type.

Aspect

Details

Transaction timing

A scheduled async function starts only after the transaction that scheduled it finishes successfully.

User

Async functions run as the same user who scheduled the async work.

Transaction scope

Each async function runs in a new transaction.

Scheduling per execution

Each script function execution can schedule one async function or one async HTTP call.

Delay

The maximum delay for a scheduled async function is 7 days.

Chain length

Async functions can schedule another async function or async HTTP call to create a chain of follow-up work. The default maximum chain length is 10 async executions.

Error handling

If an async function throws an error, YouTrack stops the remaining async call chain for that invocation.

Cleanup

Async execution contexts that remain stale for more than two days are cleaned up automatically.

06 July 2026