Portal Community

When to Use

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

FieldRequiredDescription
credentialIdRequiredBizFirstAI credential ID holding the Apify API token. The node also accepts a literal apiToken key for testing.
baseUrlOptionalApify API base URL. Defaults to https://api.apify.com.

Operation

Field (config key)RequiredDescription
resourceRequiredMust be "actor".
operationRequiredMust be "run".
actorIdRequiredThe actor to run. Accepts username~actor-name format (e.g. apify~web-scraper) or a raw actor ID string. Supports BizFirst expressions.
customBodyOptionalJSON 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.
waitForFinishOptional"true" to block until the actor finishes. Default "false" (returns immediately with RUNNING status).
timeoutOptionalMaximum actor run duration in seconds. Valid range: 1–86400. Defaults to the actor's own timeout setting. Values outside range are ignored.
memoryOptionalMemory allocation in MB. Valid values: 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768. Defaults to 1024. Invalid values silently reset to 1024.
buildOptionalActor 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

ErrorCause
API token is requiredcredentialId / apiToken is missing or empty.
Actor ID is requiredactorId is missing or empty.
Invalid settings for actor/runInternal 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

FieldTypeDescription
runIdstringUnique identifier for this actor run. Use with actor-run/get to poll status.
actorIdstringThe actor that was run.
runStatusstringRun status at response time: READY, RUNNING, SUCCEEDED, FAILED, TIMED-OUT, ABORTING, or ABORTED.
startedAtstringISO 8601 timestamp when the run started. Empty string if not yet started.
finishedAtstringISO 8601 timestamp when the run finished. Empty string if still running.
defaultDatasetIdstringID of the default dataset for this run. Pass to dataset/getItems to read scraped output.
defaultKeyValueStoreIdstringID of the default key-value store for this run.
defaultRequestQueueIdstringID of the default request queue for this run.
usageTotalUsdnumberTotal compute cost in USD at time of response. May be partial if the run is still executing.
exitCodenumberActor 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

ExpressionReturns
{{ $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

PolicyRecommendationSeverity
API token storageAlways use a BizFirstAI credential record (credentialId). Never embed raw API tokens in workflow configuration JSON — tokens appear in audit logs and exports.Critical
Memory capSet 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 enforcementAlways set timeout to cap run duration. Without a timeout, a misbehaving actor can run for 24 hours and incur significant costs.High
Build pinningUse a pinned build tag in production. Defaulting to "latest" means actor updates can silently change output structure and break downstream data processing.Medium
Async pollingFor 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 handlingAlways connect the error port. An unhandled error from a long-running actor can silently drop data without alerting the workflow.Medium
Input validationValidate 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.