When to Use
- Async run polling: After launching an actor with
actor/run (no waitForFinish), use this node inside a Loop + Delay pattern to check runStatus every 30–60 seconds until it reaches SUCCEEDED or a terminal failure state.
- Retrieving dataset ID after async run: Once a run is confirmed
SUCCEEDED, read defaultDatasetId from this node's output and pass it to dataset/getItems to retrieve the scraped data.
- Billing and cost tracking: After a run completes, fetch its metadata to capture
usageTotalUsd and log actual compute costs per run for budget monitoring and chargebacks.
- Exit code verification: For actors that signal specific outcomes via exit codes (0 = no data, 1 = partial data, 2 = full data), use
exitCode in an IfCondition to route to different downstream processing paths.
- Run provenance tracking: Store
startedAt, finishedAt, and usageTotalUsd in an audit database for each workflow execution to maintain a complete history of scraping operations.
Polling pattern: A typical async polling workflow: actor/run (store runId) → loop start → Delay (30–60s) → actor-run/get → IfCondition (runStatus === "RUNNING" → continue loop, else → exit loop) → loop end → dataset/getItems. Always add a maximum loop iteration count to prevent infinite polling if an actor stalls.
Configuration
Connection
| Field | Required | Description |
credentialId | Required | BizFirstAI credential ID holding the Apify API token. |
baseUrl | Optional | Apify API base URL. Defaults to https://api.apify.com. |
Operation
| Field (config key) | Required | Description |
resource | Required | Must be "actor-run". |
operation | Required | Must be "get-run". |
runId | Required | The Apify run ID to fetch. Obtained from any run operation output field runId. Supports BizFirst expressions, e.g. {{ $output.runnerNode.runId }}. |
Sample Configuration
{
"resource": "actor-run",
"operation": "get-run",
"credentialId": "apify-prod-token",
"runId": "{{ $output.actorRunNode.runId }}"
}
Validation Errors
| Error | Cause |
API token is required | credentialId / apiToken is missing or empty. |
Run ID is required | runId is missing or empty. |
Invalid settings for actor-run/get-run | Internal type mismatch. Verify resource is "actor-run" and operation is "get-run". |
APIFY_ERROR (error port) | Run ID not found (404), API token lacks permission to view this run, or a network error occurred. |
Output
Success Port
| Field | Type | Description |
runId | string | The run ID that was queried. |
actorId | string | The actor that produced this run. |
runStatus | string | Current run status: READY, RUNNING, SUCCEEDED, FAILED, TIMED-OUT, ABORTING, or ABORTED. |
startedAt | string | ISO 8601 timestamp when the run started. |
finishedAt | string | ISO 8601 timestamp when the run finished. Empty string if still in progress. |
defaultDatasetId | string | Default dataset ID for this run. Available even before the run finishes (dataset may be partial). |
defaultKeyValueStoreId | string | Default key-value store ID for this run. |
usageTotalUsd | number | Compute cost accumulated so far in USD. |
exitCode | number | Actor exit code. 0 = clean success, non-zero = error, -1 = still running. |
Error Port
Routes here when the run ID is not found (the run may have been deleted or the ID is wrong), authentication fails, or a network error occurs. Output contains errorCode ("APIFY_ERROR"), message, and operation ("get-run").
Sample Output
{
"runId": "run_abc123def456",
"actorId": "moJRLRc85AitArpNN",
"runStatus": "SUCCEEDED",
"startedAt": "2026-05-26T10:00:01.000Z",
"finishedAt": "2026-05-26T10:04:22.000Z",
"defaultDatasetId": "ds_g1h2i3j4k5l6",
"defaultKeyValueStoreId": "kvs_m7n8o9p0q1r2",
"usageTotalUsd": 0.0341,
"exitCode": 0
}
Expression Reference
| Expression | Returns |
{{ $output.apify.runStatus }} | Status string — use in IfCondition to branch on "SUCCEEDED" vs "RUNNING". |
{{ $output.apify.defaultDatasetId }} | Dataset ID to pass to dataset/getItems once run is complete. |
{{ $output.apify.exitCode }} | Exit code for actor-level outcome branching. |
{{ $output.apify.usageTotalUsd }} | Accumulated compute cost for billing audit. |
{{ $output.apify.finishedAt }} | Completion timestamp for SLA monitoring. |
{{ $output.apify.runId }} | Run ID (echoed from input) for downstream logging. |
Node Policies & GuardRails
| Policy | Recommendation | Severity |
| API token storage | Use credentialId; never embed raw tokens. | Critical |
| Polling interval | Use a Delay of at least 15–30 seconds between polls. Polling faster than 10 seconds provides no benefit and wastes Apify API rate limit quota. | High |
| Max iterations guard | Set a maximum iteration count on the Loop node wrapping this poll. Without it, a permanently-stuck RUNNING run causes an infinite loop. | High |
| Terminal state check | Branch on all terminal states: SUCCEEDED, FAILED, TIMED-OUT, ABORTED. Do not only check for SUCCEEDED — unhandled failure states cause the loop to exhaust its iteration count before alerting. | High |
| Partial dataset reads | The defaultDatasetId is available even while the run is still RUNNING — items are appended live. Only read from the dataset after runStatus is SUCCEEDED to ensure the dataset is complete. | Medium |
Examples
Async Polling Pattern — Check and Continue
// Step 1: actor/run (waitForFinish: false) → stores runId variable
// Step 2: Loop node (max 20 iterations)
// Step 2a: Delay node (30 seconds)
// Step 2b: actor-run/get
{
"resource": "actor-run",
"operation": "get-run",
"credentialId": "apify-prod-token",
"runId": "{{ $variables.scrapeRunId }}"
}
// Step 2c: IfCondition: runStatus === "RUNNING" → continue loop
// runStatus === "SUCCEEDED" → break loop
// else → error handler
// Step 3: dataset/getItems using defaultDatasetId from Step 2b
The standard async scraping pattern. The run ID from the initial actor/run is stored in a workflow variable. The loop polls every 30 seconds with a 20-iteration cap (10-minute max wait). Once SUCCEEDED, the dataset ID is passed to retrieval.
Post-Run Cost Audit
{
"resource": "actor-run",
"operation": "get-run",
"credentialId": "apify-billing-token",
"runId": "{{ $output.previousRun.runId }}"
}
After a workflow that triggers multiple actor runs, a final audit step calls this node for each runId stored during execution. The usageTotalUsd, startedAt, and finishedAt values are written to a billing log table for monthly cost reconciliation.
Exit Code Based Routing
{
"resource": "actor-run",
"operation": "get-run",
"credentialId": "apify-prod-token",
"runId": "{{ $variables.runId }}"
}
// IfCondition branches:
// exitCode === 0 → proceed to dataset retrieval
// exitCode === 1 → log partial success, fetch partial dataset
// exitCode > 1 → trigger alert, skip dataset retrieval
For actors that use exit codes to communicate outcome severity, use an IfCondition node after actor-run/get to route to different processing paths based on the exit code value.