When to Use
- Asynchronous scraping pipelines: Fire an actor run and immediately return its
runId. Store it in a workflow variable, then use a Loop + Delay + actor-run/get pattern to poll for completion without blocking the workflow thread for the full duration.
- Competitive intelligence: Trigger a price-monitoring actor on a competitor's product catalogue whenever a sales event is detected. Pass dynamic URL lists via
CustomBody and collect the defaultDatasetId to read results once the run finishes.
- Lead generation: On a scheduled trigger, run a LinkedIn or directory scraper actor with a targeted search payload, then pipe the run's dataset into a CRM enrichment workflow.
- On-demand SEO audits: When a user submits a domain in a form, trigger an SEO audit actor with the domain as input and return the
runId so the UI can poll for results via a webhook callback.
- Controlled resource allocation: Use
MemoryMb and TimeoutSecs to cap compute costs per run — run lightweight actors at 256 MB and heavy crawls at 4096 MB, each with appropriate timeouts.
Synchronous vs asynchronous: Set waitForFinish to "true" to block until the actor completes (up to TimeoutSecs). Leave it "false" (default) to return immediately with runStatus: "RUNNING". For actors that complete in under 60 seconds, waiting is usually simpler. For actors that run for minutes or hours, use the async pattern to avoid workflow timeouts.
Configuration
Connection
| Field | Required | Description |
credentialId | Required | BizFirstAI credential ID holding the Apify API token. The node also accepts a literal apiToken key for testing. |
baseUrl | Optional | Apify API base URL. Defaults to https://api.apify.com. |
Operation
| Field (config key) | Required | Description |
resource | Required | Must be "actor". |
operation | Required | Must be "run". |
actorId | Required | The actor to run. Accepts username~actor-name format (e.g. apify~web-scraper) or a raw actor ID string. Supports BizFirst expressions. |
customBody | Optional | JSON string passed as the actor's input. Must be a valid JSON object serialized as a string. If omitted, the actor runs with its default input or an empty object. |
waitForFinish | Optional | "true" to block until the actor finishes. Default "false" (returns immediately with RUNNING status). |
timeout | Optional | Maximum actor run duration in seconds. Valid range: 1–86400. Defaults to the actor's own timeout setting. Values outside range are ignored. |
memory | Optional | Memory allocation in MB. Valid values: 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768. Defaults to 1024. Invalid values silently reset to 1024. |
build | Optional | Actor build tag or build ID to run. Defaults to "latest". Use a pinned build tag (e.g. "1.2.3") for production stability. |
Sample Configuration
{
"resource": "actor",
"operation": "run",
"credentialId": "apify-prod-token",
"actorId": "apify~web-scraper",
"customBody": "{\"startUrls\":[{\"url\":\"https://example.com/products\"}],\"pageFunction\":\"async function pageFunction(context){return{title:context.$('h1').text(),price:context.$('.price').text()}}\" }",
"waitForFinish": "false",
"timeout": "300",
"memory": "1024",
"build": "latest"
}
Validation Errors
| Error | Cause |
API token is required | credentialId / apiToken is missing or empty. |
Actor ID is required | actorId is missing or empty. |
Invalid settings for actor/run | Internal settings type mismatch. Verify resource is "actor" and operation is "run". |
APIFY_ERROR (error port) | Apify API returned a non-success response — invalid actor ID, insufficient permissions, Apify quota exceeded, or network error. The error message field contains the API error detail. |
Output
Success Port
| Field | Type | Description |
runId | string | Unique identifier for this actor run. Use with actor-run/get to poll status. |
actorId | string | The actor that was run. |
runStatus | string | Run status at response time: READY, RUNNING, SUCCEEDED, FAILED, TIMED-OUT, ABORTING, or ABORTED. |
startedAt | string | ISO 8601 timestamp when the run started. Empty string if not yet started. |
finishedAt | string | ISO 8601 timestamp when the run finished. Empty string if still running. |
defaultDatasetId | string | ID of the default dataset for this run. Pass to dataset/getItems to read scraped output. |
defaultKeyValueStoreId | string | ID of the default key-value store for this run. |
defaultRequestQueueId | string | ID of the default request queue for this run. |
usageTotalUsd | number | Total compute cost in USD at time of response. May be partial if the run is still executing. |
exitCode | number | Actor process exit code. 0 = success, non-zero = error, -1 if not yet finished. |
Error Port
Routes here when the Apify API returns an error, the actor ID is invalid, the API token lacks permission, or a network failure occurs. The output contains errorCode ("APIFY_ERROR"), message with the raw API error detail, and operation ("run").
Sample Output
{
"runId": "abc123xyz456",
"actorId": "moJRLRc85AitArpNN",
"runStatus": "RUNNING",
"startedAt": "2026-05-26T09:15:32.000Z",
"finishedAt": "",
"defaultDatasetId": "ds_a1b2c3d4e5f6",
"defaultKeyValueStoreId": "kvs_x9y8z7w6v5",
"defaultRequestQueueId": "rq_q1w2e3r4t5",
"usageTotalUsd": 0.0012,
"exitCode": -1
}
Expression Reference
| Expression | Returns |
{{ $output.apify.runId }} | Run ID to pass to polling nodes. |
{{ $output.apify.runStatus }} | Current run status string. |
{{ $output.apify.defaultDatasetId }} | Dataset ID for use in dataset/getItems. |
{{ $output.apify.defaultKeyValueStoreId }} | KV store ID for use in key-value-store/getRecord. |
{{ $output.apify.usageTotalUsd }} | Compute cost in USD. |
{{ $output.apify.exitCode }} | Actor exit code. Check === 0 for clean completion. |
Node Policies & GuardRails
| Policy | Recommendation | Severity |
| API token storage | Always use a BizFirstAI credential record (credentialId). Never embed raw API tokens in workflow configuration JSON — tokens appear in audit logs and exports. | Critical |
| Memory cap | Set explicit memory values per actor to prevent runaway compute costs. Default 1024 MB is appropriate for most scraping tasks; reduce to 256 MB for lightweight HTTP actors. | High |
| Timeout enforcement | Always set timeout to cap run duration. Without a timeout, a misbehaving actor can run for 24 hours and incur significant costs. | High |
| Build pinning | Use a pinned build tag in production. Defaulting to "latest" means actor updates can silently change output structure and break downstream data processing. | Medium |
| Async polling | For actors expected to run longer than 60 seconds, use waitForFinish: false and poll with actor-run/get to avoid blocking the workflow engine thread. | Medium |
| Error port handling | Always connect the error port. An unhandled error from a long-running actor can silently drop data without alerting the workflow. | Medium |
| Input validation | Validate customBody JSON structure before passing to the node. Malformed JSON causes an Apify API 400 error routed to the error port. | Low |
Examples
E-Commerce Price Monitor — Async Run
{
"resource": "actor",
"operation": "run",
"credentialId": "apify-prod-token",
"actorId": "apify~cheerio-scraper",
"customBody": "{\"startUrls\":[{\"url\":\"https://shop.example.com/laptops\"},{\"url\":\"https://shop.example.com/tablets\"}],\"pseudoUrls\":[{\"purl\":\"https://shop.example.com/[.*]\"}],\"maxPagesPerCrawl\":200}",
"waitForFinish": "false",
"timeout": "600",
"memory": "1024",
"build": "latest"
}
Fires a Cheerio scraper across two product category pages. The run ID is stored in a variable; a subsequent polling loop checks runStatus every 30 seconds and routes to dataset retrieval once SUCCEEDED.
Lead Generation — Synchronous Run with Wait
{
"resource": "actor",
"operation": "run",
"credentialId": "apify-leads-token",
"actorId": "curious_coder~contact-info-scraper",
"customBody": "{\"queries\":[\"software engineers San Francisco\"],\"maxResults\":50}",
"waitForFinish": "true",
"timeout": "120",
"memory": "512",
"build": "1.4.0"
}
Runs a contact scraper synchronously with a pinned build. Because waitForFinish is "true", the workflow blocks until the actor finishes (up to 120 seconds) before continuing. The pinned build "1.4.0" ensures output structure stability.
Dynamic Actor ID from Previous Node
{
"resource": "actor",
"operation": "run",
"credentialId": "apify-prod-token",
"actorId": "{{ $output.configNode.selectedActorId }}",
"customBody": "{{ $output.inputBuilder.serializedJson }}",
"waitForFinish": "false",
"timeout": "{{ $output.configNode.timeoutSecs }}",
"memory": "2048"
}
Demonstrates BizFirst expression support: actor ID, custom body, and timeout are all resolved from upstream node outputs, enabling a fully dynamic actor dispatcher pattern.