Skip to content
Use Actors

Run Actors

Start runs from the dashboard, API, clients, or CLI, with input, run options, and limits.

A run is input (a JSON object) plus run options such as memory and timeout. Start one from the dashboard, the API, a client, or the CLI:

curl -X POST "https://api.scrape.ly/v2/actors/jane~google-maps-scraper/runs?memory=1024&timeout=600" \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms": ["coffee"], "maxResults": 50}'
ToSee
Run from the browserRun from the dashboard
Start, wait for, or sync-run over HTTPRun from the API
Set memory, timeout, cost cap, buildQuery parameters
Watch, abort, rerun, resurrectMonitor runs, Abort, rerun, and resurrect
Fix a 4xxLimits and errors

Run from the dashboard

Open the Actor from the Store or from Actors in the side menu.

Actors (the Used actors tab, next to Saved inputs) lists the Actors you've created or run, most recently run first (Last run started). Use the same dropdown to show everything (Pricing model) or one pricing model (Free or Pay per event), and Last run status to filter by how the last run ended. My Actors (under Development) lists only your own Actors, in creation date order; pick Last run started there to sort by last run instead. Clicking a column header overrides either order.

Start (in the page header and at the bottom of Input) runs exactly what the input form shows, with the run options shown under it. Both buttons do the same thing.

  • If the form shows one of your saved inputs unchanged, the run is recorded against it: it appears in that saved input's runs and counts as its last use.
  • If you changed the form, or picked an example, Defaults or a recent run, the run starts with the form's input as it is. A message then offers Save as… or Update “name” so you can keep the input.

The run page opens next. An Actor marked Under Maintenance asks you to confirm with Run anyway; an unapproved Full Access Actor asks for Approve & Run (see Permissions).

Input: form or JSON

The Input tab's Form / JSON toggle switches between a form generated from the input schema and the raw JSON object (handy for API calls; it reports Invalid JSON. or Input must be a JSON object. until valid).

Under the form, API & MCP shows how to run the same input from code: snippets for HTTP / cURL, JavaScript, Python and the CLI built from the input in the form, the MCP setup for AI agents, and the Actor's OpenAPI definition. Use my API token puts your API key into the snippets. The section is closed until you open it and stays the way you left it. On your own Actors it is under Source → Input.

When a build's input schema differs from the one an input was saved with, the form fits the input to it: fields the schema no longer has are hidden and not sent, and new fields get their default or prefill.

Saved inputs

The Input dropdown above the form fills the form from one of these, in this order:

SectionWhat it holds
Your saved inputsInputs you saved for this Actor. Your default (marked Default) comes first, then the most recently used
ExamplesReady-made inputs from the Actor's developer: published example tasks and presets. They can't be overwritten. An example marked May be unreliable failed its recent automatic tests, so it may return fewer results or none
DefaultsThe input schema's default and prefill values
Recent runsThe inputs of your last three runs of this Actor

The page opens with your default saved input, or the first example, or Defaults. Picking an entry only fills the form; nothing runs until you press Start. If you changed the form, you're asked before your changes are replaced.

ActionDoes
Save “name”Overwrites the selected saved input with the form and its run options. Shown when you changed one of your own saved inputs
Save as new…Saves the form as a new saved input under a name you choose, optionally as your default
Rename…, Duplicate, Delete…Manage the selected saved input. Delete… lists the automations that still use it
Set as defaultThe default opens first on this Actor's page
Copy linkA link that opens this Actor's page with that entry selected
Automate thisOpens a new automation that runs the selected saved input. If the form has unsaved changes, or shows an example, you save it as a new saved input first

Each saved input in the dropdown shows its run count, when it was last used, and how many automations use it. Manage all saved inputs at the bottom of the dropdown opens Actors → Saved inputs, the list of saved inputs across all your Actors, searched for this Actor.

A saved input is a task in the API, so the same saved inputs work with POST /v2/actor-tasks/{taskId}/runs, the clients' task() calls and the CLI. The API & MCP section under the input form (closed until you open it) shows snippets By reference (they run the saved input as stored) or with the input Inline. Secret fields are stored but shown masked.

Run options

Under the form, Run options (collapsed) shows memory, timeout and maximum cost:

OptionWhat it does
Memory128 MB to 16 GB. CPU scales with memory (4 GB gets one CPU core), and so does the compute cost per minute. Your account's maximum per run still applies.
TimeoutSeconds before the run is stopped. No timeout leaves it unset, so the Actor's default timeout applies, or 3600 seconds if the Actor has none.
Maximum cost per runA USD cap on the run's total charges (platform usage plus the Actor's fee). No maximum limit removes the cap.

Run options are saved with each saved input; changing them counts as an unsaved change. Examples and Defaults start from the Actor's default options. On someone else's Actor there is no build option: your runs always use the build the publisher picked (the User Build).

Run from the API

Authenticate with Authorization: Bearer <token>. Create a token under Settings → API & Integrations.

Refer to an Actor by its ID or by username~name (for example jane~google-maps-scraper). ~name alone refers to one of your own Actors.

POST/v2/actors/{actorId}/runs
POST/v2/actors/{actorId}/run-sync
POST/v2/actors/{actorId}/run-sync-get-dataset-items

In all three, the request body is the Actor's input as a JSON object. Run options go in the query string.

Start a run (asynchronous)

POST /v2/actors/{actorId}/runs starts the run and returns immediately with 201 Created and the run object, including id, status, defaultDatasetId, and defaultKeyValueStoreId. The Location header points at /v2/actor-runs/{runId}.

Add waitForFinish=<seconds> (up to 60) to make the request wait for the run to finish before it returns. The wait stops at 45 seconds. If the run is still going when the wait ends, you get the run in its current state.

If your code retries failed requests, send an Idempotency-Key header with the start request. A retry with the same key returns the run that already started instead of starting a second one. See Idempotent run starts.

Run synchronously

The synchronous endpoints start a run, wait for it, and return the results in the same response:

  • run-sync returns the run's OUTPUT record from its default key-value store, or {} if the Actor didn't write one. Pass outputRecordKey to return a different record.
  • run-sync-get-dataset-items returns the run's dataset items. It accepts all the dataset item parameters, such as format, fields, clean, and limit.

Both wait at most 45 seconds and cap the run's timeout at 300 seconds. If the run hasn't finished after 45 seconds, you get 408 run-timeout-exceeded with the run ID in the message. The run keeps going, so wait for it as described below instead of calling the endpoint again. If it finishes with any status other than SUCCEEDED, you get 400 run-failed. Use the asynchronous endpoint for longer jobs.

Both synchronous endpoints also accept GET, which runs the Actor with an empty input.

Wait for a run and check its status

GET /v2/actor-runs/{runId}?waitForFinish=60 returns the run as soon as it finishes, or after 45 seconds with the run in its current state. Repeat it until status is terminal; the official clients' call() and waitForFinish() do this for you. For a run started elsewhere, GET /v2/actors/{actorId}/runs/last?waitForFinish=60 waits the same way for your latest run of the Actor. Filter it with status, for example status=SUCCEEDED.

GET/v2/actors/{actorId}/runs/last?status=SUCCEEDED
GET/v2/actor-runs/{runId}

Query parameters

ParameterValuesDefault
buildBuild tag or number. Ignored on someone else's Actor, which always runs the User Build.The Actor's default build, else latest
memoryMegabytes; a power of two (128, 256, 512, 1024, …) within your limitsThe Actor's default, else 2048
timeoutSeconds; a positive integerThe Actor's default, else 3600
maxTotalChargeUsdUSD, a non-negative decimalThe Actor's minimum, if set; otherwise no cap
maxItemsIntegerThe Actor's default, if any
restartOnErrortrue/1 or false/0The Actor's default, else false
waitForFinish0–60 seconds; the wait stops at 450
webhooksBase64-encoded JSON array of ad-hoc webhooksNone
forcePermissionLevelLIMITED_PERMISSIONS to run a Full Access Actor with limited accessThe Actor's level

Notes on the less obvious options:

  • maxTotalChargeUsd caps the run's total charges: compute, storage, data transfer, proxy, Scrape.ly browser credits, LLM gateway requests, and the Actor's fee. When the cap is reached, the run is stopped and the Actor fee is limited to what fits under the cap.
  • maxItems is passed to the Actor as ACTOR_MAX_PAID_DATASET_ITEMS. Actors that charge per result item are expected to stop after that many results, and the platform never bills more result-item events than maxItems. Other events still count, so use maxTotalChargeUsd for a hard limit on the whole run.
  • restartOnError: if the run fails, Scrape.ly starts one new run with the same input and options. The new run has its own ID and storages.
  • webhooks: see Ad-hoc webhooks.

Invalid values return 400: invalid-timeout, invalid-memory, or invalid-max-total-charge.

Run from code

The clients wrap the same endpoints. Install with npm install scrapely-client or pip install scrapely-client-python.

import { ScrapelyClient } from 'scrapely-client';

const client = new ScrapelyClient({
    token: process.env.SCRAPELY_TOKEN,
    baseUrl: 'https://api.scrape.ly',
});

// Start the run and wait for it to finish
const run = await client.actor('jane~google-maps-scraper').call(
    { searchTerms: ['coffee'], maxResults: 50 },
    { memory: 1024, timeout: 600, maxTotalChargeUsd: 2 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Use .start(input, options) instead of .call() to return as soon as the run is created. See the JavaScript client and Python client guides.

Run from the CLI

The CLI can run any Actor you have access to, including Store Actors:

.bash
npm install -g scrapely-cli
scrapely login

# Run and wait, streaming the log; print the dataset at the end
scrapely call jane~google-maps-scraper \
  --input '{"searchTerms": ["coffee"], "maxResults": 50}' \
  --memory 1024 --timeout 600 --output-dataset

# Start and return immediately
scrapely actors start jane~google-maps-scraper --input-file input.json

call and actors start accept --input, --input-file (or - for stdin), --build (your own Actors only), --memory, --timeout, and --json. They don't expose maxTotalChargeUsd; use the API or a client if you need a cost cap. scrapely run is different: it runs the Actor project in your current directory.

To follow runs from the CLI, use scrapely runs ls, runs info <runId>, runs log <runId>, runs wait <runId>, runs abort <runId>, and runs resurrect <runId>. See CLI runs & builds.

Monitor runs

Runs in the side menu lists all your runs. Filter it by status or origin, or search. Each Actor page also has a Runs tab with just that Actor's runs.

A run moves through these statuses:

StatusMeaning
READYCreated, waiting for a worker
RUNNINGThe Actor is running
SUCCEEDEDFinished successfully
FAILEDThe Actor exited with an error
ABORTING / ABORTEDBeing stopped, or stopped, at your request
TIMING-OUT / TIMED-OUTBeing stopped, or stopped, because the timeout was reached

A resurrected run goes back to RUNNING. RESURRECTED only appears as the ACTOR.RUN.RESURRECTED webhook event.

The run page shows the status, live CPU and memory, and these tabs: Log, Input, Output (when the Actor defines one), Storage (Dataset, Key-value store, Request queue), and Automations (the deliveries of automations that reacted to this run). Show details reveals the run ID, origin, start and finish times, build, memory, timeout, maximum cost, and the Cost; click the cost for a breakdown.

From the API:

GET/v2/actor-runs
GET/v2/actors/{actorId}/runs
GET/v2/actor-runs/{runId}
GET/v2/actor-runs/{runId}/log
GET/v2/actor-runs/{runId}/input

The run lists accept status (comma-separated), startedAfter, startedBefore, offset, limit, and desc. GET /v2/actor-runs also accepts origin and search. The log is returned as plain text.

GET/v2/actor-runs?status=SUCCEEDED&limit=5&desc=true

Abort, rerun, and resurrect

Dashboard (run page)APIDoes
AbortPOST /v2/actor-runs/{runId}/abortStops a running run
Actions → RerunStart a new runNew run with the same input and options
Actions → ResurrectPOST /v2/actor-runs/{runId}/resurrectRestarts a finished run
Actions → DeleteDELETE /v2/actor-runs/{runId}Removes the run
  • Abort with gracefully=true first tells the Actor to save its state and stop, instead of killing it right away. A run that hasn't started yet is aborted at once and its reserved credits are released.
  • Resurrect works on SUCCEEDED, FAILED, ABORTED, and TIMED-OUT runs. The run keeps its ID and storages, so a crawler can continue where it stopped. You can override build (on your own Actors only), timeout, memory, maxItems, maxTotalChargeUsd, and restartOnError. A resurrected run is billed again and checked against your balance and limits like a new run.

Limits and errors

Your account limits are under Billing → Limits and in GET /v2/users/me/limits. The ones that affect runs:

LimitCaps
Concurrent runsRuns active at once
Total memoryCombined memory of all your active runs
Memory per runMinimum and maximum for one run (128 MB and 8 GB by default)
API rate limitRequests per minute to the API
StatusError typeCause and fix
400invalid-memoryMemory is not a power of two, or is outside your per-run limits.
400limit-exceededThis run would take your active runs over your total memory limit. Wait for runs to finish or use less memory.
400no-successful-buildYour Actor has no successful build to run.
400actor-not-availableSomeone else's Actor can't be run right now.
400unsupported-pricingThe Actor uses a pricing model Scrape.ly can't run.
402payment-requiredYour balance can't cover the run's estimated cost (timeout × memory × compute price, plus the Actor's event prices). Top up, or lower timeout or memory.
403forbiddenThe Actor is private and isn't yours.
403full-permission-actor-not-approvedApprove the Actor in the dashboard or with POST /v2/actors/{actorId}/approve-permissions, then start the run again.
404actor-not-foundCheck the Actor ID or username~name.
429concurrency-limit-exceededYou're at your concurrent-runs limit. Retry when a run finishes.
429run-capacity-check-busyAnother run request from your account is being checked (synchronous endpoints). Retry shortly.

What's next