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}'| To | See |
|---|---|
| Run from the browser | Run from the dashboard |
| Start, wait for, or sync-run over HTTP | Run from the API |
| Set memory, timeout, cost cap, build | Query parameters |
| Watch, abort, rerun, resurrect | Monitor runs, Abort, rerun, and resurrect |
| Fix a 4xx | Limits 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:
| Section | What it holds |
|---|---|
| Your saved inputs | Inputs you saved for this Actor. Your default (marked Default) comes first, then the most recently used |
| Examples | Ready-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 |
| Defaults | The input schema's default and prefill values |
| Recent runs | The 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.
| Action | Does |
|---|---|
| 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 default | The default opens first on this Actor's page |
| Copy link | A link that opens this Actor's page with that entry selected |
| Automate this | Opens 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:
| Option | What it does |
|---|---|
| Memory | 128 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. |
| Timeout | Seconds 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 run | A 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.
/v2/actors/{actorId}/runs/v2/actors/{actorId}/run-sync/v2/actors/{actorId}/run-sync-get-dataset-itemsIn 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-syncreturns the run'sOUTPUTrecord from its default key-value store, or{}if the Actor didn't write one. PassoutputRecordKeyto return a different record.run-sync-get-dataset-itemsreturns the run's dataset items. It accepts all the dataset item parameters, such asformat,fields,clean, andlimit.
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.
/v2/actors/{actorId}/runs/last?status=SUCCEEDED/v2/actor-runs/{runId}Query parameters
| Parameter | Values | Default |
|---|---|---|
build | Build tag or number. Ignored on someone else's Actor, which always runs the User Build. | The Actor's default build, else latest |
memory | Megabytes; a power of two (128, 256, 512, 1024, …) within your limits | The Actor's default, else 2048 |
timeout | Seconds; a positive integer | The Actor's default, else 3600 |
maxTotalChargeUsd | USD, a non-negative decimal | The Actor's minimum, if set; otherwise no cap |
maxItems | Integer | The Actor's default, if any |
restartOnError | true/1 or false/0 | The Actor's default, else false |
waitForFinish | 0–60 seconds; the wait stops at 45 | 0 |
webhooks | Base64-encoded JSON array of ad-hoc webhooks | None |
forcePermissionLevel | LIMITED_PERMISSIONS to run a Full Access Actor with limited access | The Actor's level |
Notes on the less obvious options:
maxTotalChargeUsdcaps 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.maxItemsis passed to the Actor asACTOR_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 thanmaxItems. Other events still count, so usemaxTotalChargeUsdfor 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:
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.jsoncall 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:
| Status | Meaning |
|---|---|
READY | Created, waiting for a worker |
RUNNING | The Actor is running |
SUCCEEDED | Finished successfully |
FAILED | The Actor exited with an error |
ABORTING / ABORTED | Being stopped, or stopped, at your request |
TIMING-OUT / TIMED-OUT | Being 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:
/v2/actor-runs/v2/actors/{actorId}/runs/v2/actor-runs/{runId}/v2/actor-runs/{runId}/log/v2/actor-runs/{runId}/inputThe 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.
/v2/actor-runs?status=SUCCEEDED&limit=5&desc=trueAbort, rerun, and resurrect
| Dashboard (run page) | API | Does |
|---|---|---|
| Abort | POST /v2/actor-runs/{runId}/abort | Stops a running run |
| Actions → Rerun | Start a new run | New run with the same input and options |
| Actions → Resurrect | POST /v2/actor-runs/{runId}/resurrect | Restarts a finished run |
| Actions → Delete | DELETE /v2/actor-runs/{runId} | Removes the run |
- Abort with
gracefully=truefirst 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, andTIMED-OUTruns. The run keeps its ID and storages, so a crawler can continue where it stopped. You can overridebuild(on your own Actors only),timeout,memory,maxItems,maxTotalChargeUsd, andrestartOnError. 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:
| Limit | Caps |
|---|---|
| Concurrent runs | Runs active at once |
| Total memory | Combined memory of all your active runs |
| Memory per run | Minimum and maximum for one run (128 MB and 8 GB by default) |
| API rate limit | Requests per minute to the API |
| Status | Error type | Cause and fix |
|---|---|---|
400 | invalid-memory | Memory is not a power of two, or is outside your per-run limits. |
400 | limit-exceeded | This run would take your active runs over your total memory limit. Wait for runs to finish or use less memory. |
400 | no-successful-build | Your Actor has no successful build to run. |
400 | actor-not-available | Someone else's Actor can't be run right now. |
400 | unsupported-pricing | The Actor uses a pricing model Scrape.ly can't run. |
402 | payment-required | Your 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. |
403 | forbidden | The Actor is private and isn't yours. |
403 | full-permission-actor-not-approved | Approve the Actor in the dashboard or with POST /v2/actors/{actorId}/approve-permissions, then start the run again. |
404 | actor-not-found | Check the Actor ID or username~name. |
429 | concurrency-limit-exceeded | You're at your concurrent-runs limit. Retry when a run finishes. |
429 | run-capacity-check-busy | Another run request from your account is being checked (synchronous endpoints). Retry shortly. |
What's next
- Results & exports
- Integrations: tasks, schedules, and webhooks
- Runs API reference and Actors API reference