Skip to navigation

Using Wait Until steps

Use a Wait Until step when a Flow must wait before it continues. The step does one or both of these things:

  • Waits for a fixed delay.
  • Polls an HTTP endpoint until the response meets a success condition, such as a job status of done.

When you set both, the step waits for the delay first, then starts polling.

Add a Wait Until step in the dashboard

To add the step, follow these steps:

  1. In the Flow editor, click the + control where you want to insert the step.
  2. In the step picker, under Actions, select Wait Until.
  3. In Wait, enter the delay in milliseconds. Leave it empty to start polling right away.
  4. To poll an endpoint, turn on Enable HTTP polling, then configure the request:
    1. Choose the HTTP method and enter the URL. The URL accepts Flow variables, such as {{jobId}}, and secret references, such as {{secret:API_KEY}}.
    2. In every, enter the time between attempts in milliseconds. The minimum is 100.
    3. In up to, enter the maximum number of attempts.
    4. Under Success when, choose a condition. For the options, see Choose a success condition.
    5. Optional: under Headers, add request headers. Under Advanced, set the response type and the timeout (ms) for each request.
  5. Set the output variable. A new step uses wait_result.
  6. Choose the step’s error handling mode. A new step starts with Stop on error. For what each mode does, see Handle a poll that never succeeds.

Add a Wait Until step to a Flow definition

A wait-until step takes these fields in its config:

  • delayMs: the delay before polling, in milliseconds.
  • poll: the polling configuration. Set delayMs, poll, or both.
  • outputVariable (required): the variable that receives the step’s result.
  • continueOnTimeout: when true, the Flow continues after a poll that never succeeds. The default is false.
  • defaultValue: the value that the output variable receives when the poll never succeeds and the Flow continues.
  • errorHandling: the error handling mode, such as { "onError": "continue" }.

The poll object takes these fields:

  • http (required): the request. It takes url, method (GET, POST, PUT, PATCH, or DELETE, default GET), headers, body, and timeout in milliseconds. When timeout is unset, each request can take up to 2 minutes.
  • intervalMs: the time between attempts. The default is 2000 and the minimum is 100.
  • maxAttempts: the maximum number of requests. The default is 10.
  • responseType: json (default) or text. With json, Runtype parses the response body so that json_path and expression conditions can read its fields.
  • success: the success condition. When it’s unset, any 2xx response succeeds.

The following step starts an export job’s poll after a 5-second delay. It checks the job every 30 seconds, up to 20 times, until the job reports done:

{
"type": "wait-until",
"name": "Wait for export job",
"config": {
"delayMs": 5000,
"poll": {
"http": {
"url": "https://api.example.com/jobs/{{jobId}}",
"method": "GET",
"headers": {
"Authorization": "Bearer {{secret:EXPORT_API_KEY}}"
}
},
"intervalMs": 30000,
"maxAttempts": 20,
"responseType": "json",
"success": {
"type": "json_path",
"jsonPath": "$.status",
"operator": "=",
"expectedValue": "done"
}
},
"outputVariable": "jobResult"
}
}

In this example, jobId is a Flow variable that an earlier step sets, and EXPORT_API_KEY is a secret in your organization. For more information about secrets, see Managing secrets.

Choose a success condition

Set success.type to one of the following conditions. The dashboard label for each condition is in parentheses.

typeDashboard optionFieldsSucceeds when
statusHTTP status code matchesstatusThe response status equals status, or is 2xx if unset
json_pathJSON path equals valuejsonPath, operator, expectedValueThe value at jsonPath passes the comparison
body_containsBody contains textbodyContainsThe raw response body contains the text
expressionCustom expressionexpressionThe JavaScript expression returns a truthy value

A request that fails, such as a network error or a request timeout, counts as an unsuccessful attempt, and the poll continues.

For a json_path condition, write the path in dot notation, such as data.state or items[0].name. A leading $. is optional. The operator field accepts =, !=, >, <, >=, <=, exists, and not-exists. Without an operator, the condition passes when the value equals expectedValue, or when the value exists if expectedValue is unset. Runtype converts an expectedValue string such as "1", "true", or "null" to a number, boolean, or null before it compares.

An expression condition can read these values:

  • status, ok, data, text, and headers from the most recent response. data is the parsed JSON body.
  • attempt: the current attempt number, starting at 1.
  • flowContext: the Flow’s variables.

For example, the expression status === 200 && data.state === 'done' succeeds when the endpoint returns 200 and a state of done.

Read the result

When the step finishes, the output variable holds an object with these fields:

  • completed: true when the success condition passed, or when the step had no poll.
  • attempts: the number of requests that the step made.
  • totalDelayMs: the time that the step spent waiting and polling.
  • lastStatus, lastResponse, lastResponseText, and lastHeaders: the status, parsed body, raw body, and headers of the last response.
  • timedOut: true when the poll used every attempt without success.
  • error: the last request error, if any.

Later steps can read the response from the last attempt. For example, in the export job example, {{jobResult.lastResponse.downloadUrl}} reads a downloadUrl field from the job’s final status response.

Handle a poll that never succeeds

If the poll uses all its attempts without meeting the success condition, the step’s error handling decides what happens:

  • With Stop on error ("onError": "fail"), the step fails and the Flow stops. A step in a Flow definition that has no errorHandling field also stops the Flow.
  • With Continue on error ("onError": "continue") or continueOnTimeout: true, the Flow continues. The output variable holds defaultValue, or null if you didn’t set one. It doesn’t hold the result object.

When the Flow continues, add a Conditional Logic step after the wait to check the output before later steps use it. For more information, see Using conditional steps.

Plan for long waits

A poll that uses a status, json_path, or body_contains condition pauses the Flow between attempts. The pause doesn’t count toward the Flow’s timeouts, so a poll can wait for hours or days.

These parts of the step keep the step running instead of pausing the Flow, so they count toward the step timeout:

  • The delayMs delay.
  • A poll with an expression condition.
  • A poll with an auth object, or with a secret reference in the request body. To send credentials in a poll that pauses, put the secret reference in a header, as the export job example does.

To wait longer than the step timeout, use a poll with a status, json_path, or body_contains condition, and set a longer intervalMs.

A pausing poll has these limits:

  • It runs at most 1,000 attempts. Runtype lowers a larger maxAttempts value to 1,000, and Flow validation reports the WAIT_UNTIL_MAX_ATTEMPTS_CLAMPED warning.
  • Its worst-case duration must be 30 days minus one hour or less. The worst case is maxAttempts times each request’s timeout, plus intervalMs for each wait between attempts. A longer poll fails validation with WAIT_UNTIL_POLL_EXCEEDS_RESUME_TTL.

A Flow that contains a Wait Until step runs through interactive dispatch. Batch runs, evals, and Schedules refuse the Flow, and an Agent’s inline Flow tools can’t contain the step. For the entry points that support pauses, see Timeouts and long-running work.

Next steps