Skip to content
API

Actor tasks

Saved inputs and run options, synchronous task runs, and published example tasks.

A task is a saved configuration for an Actor: a name, an input object, and run options. The dashboard calls tasks saved inputs (see Saved inputs); they are the same objects. All paths are relative to https://api.scrape.ly. Authentication is required, except for the public example-task endpoints. You can only access your own tasks.

Task responses use actId for the Actor ID (the create body also accepts actorId).

{taskId} can be the task ID, username~task-name, or ~task-name for one of your own tasks.

List tasks

GET/v2/actor-tasks
Query paramDescription
searchMatches the task name or the Actor name (case-insensitive).
sortBycreatedAt (default), modifiedAt, or name.
limit / offset / descPagination. Default limit is 1000; desc defaults to false.

Each item includes the Actor name and icon, totalRuns, and lastRun.

.bash
curl -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  "https://api.scrape.ly/v2/actor-tasks?limit=20&desc=1"
GET/v2/actor-tasks?limit=5

List tasks for an Actor

GET/v2/actors/{actorId}/tasks

Returns your tasks for that Actor, even if you don't own the Actor (it must be public or yours). Default limit is 20; desc defaults to newest first.

.bash
curl -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  "https://api.scrape.ly/v2/actors/eLN5rTB8sYTBWdfzx/tasks"
GET/v2/actors/{actorId}/tasks

Saved inputs for an Actor

GET/v2/actors/{actorId}/saved-inputs
GET/v2/acts/{actorId}/input-presets

saved-inputs returns what the dashboard's Input dropdown shows, in one call: your tasks for the Actor (default first, then most recently used, each with totalRuns, lastRun and the automations that use it), the Actor's examples with their input (secret fields masked), and your last three runs of the Actor. input-presets is public and returns only the examples.

examples lists the published example tasks first (id e:<slug>, source: "example"), then the presets the owner marked in the Actor's scenarios (id s:<scenario name>, source: "scenario", with slug, order, and reliability). reliability is ok, degraded (the latest automatic test cycle confirmed a failure; the dashboard shows May be unreliable), or untested. Hidden presets, and entries with the same input as an earlier one, are left out. Use the id in a link: ?input=s:<scenario name> on the Actor's page selects that entry.

.json
{
  "data": {
    "savedInputs": [
      { "id": "tAsKiDeXaMpLe123", "name": "maps-dentists-austin", "title": "Dentists in Austin", "isDefault": true,
        "lastUsedAt": "2026-08-20T09:00:00.000Z", "modifiedAt": "2026-08-14T15:00:00.000Z", "totalRuns": 12,
        "lastRun": { "id": "rUnIdExAmPlE1234", "status": "SUCCEEDED", "startedAt": "2026-08-20T09:00:00.000Z" },
        "automations": [] }
    ],
    "examples": [
      { "id": "e:restaurants-berlin", "source": "example", "title": "Restaurants in Berlin, 20 places", "description": "…", "input": { "searchTerms": ["restaurant"] }, "reliability": null },
      { "id": "s:search-dentists", "source": "scenario", "slug": "search-dentists", "title": "Dentists in Austin, 10 places", "description": null, "input": { "searchTerms": ["dentist"], "location": "Austin" }, "order": 1, "reliability": "ok" }
    ],
    "recentRuns": [ { "id": "rUnIdExAmPlE1234", "status": "SUCCEEDED", "startedAt": "2026-08-20T09:00:00.000Z", "taskId": "tAsKiDeXaMpLe123" } ]
  }
}
GET/v2/actors/{actorId}/saved-inputs

Create task

POST/v2/actor-tasks

The Actor must be public or yours, and must have at least one successful build. Task names are unique per user and at most 30 characters. Input is limited to 9 MB. Returns 201 and a Location header.

Body fieldTypeRequiredDescription
actIdstringYesActor ID or username~name. actorId is accepted as an alias.
namestringYes, unless title is setTask name (max 30 characters, unique per user). Without it, a name is generated from the Actor name and title (-2, -3… on a clash).
titlestringNoDisplay title (the name shown in the dashboard).
inputobjectNoSaved input. An empty object is filled from the schema defaults and prefills of the build you run (the default build on your own Actor, the User Build on someone else's).
optionsobjectNobuild, timeoutSecs, memoryMbytes (a power of two), maxItems, maxTotalChargeUsd, restartOnError. build only applies to your own Actors; others run the User Build, and build is dropped from the task on create and update.
seoTitle / seoDescriptionstringNoText for the task's public page if you publish it.
isDefaultbooleanNoMakes this your default saved input for the Actor (the one the dashboard opens first). Clears the flag on your other tasks for the same Actor.
.bash
curl -X POST https://api.scrape.ly/v2/actor-tasks \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "actId": "eLN5rTB8sYTBWdfzx",
    "name": "daily-scrape",
    "title": "Daily scrape",
    "input": { "url": "https://example.com" },
    "options": { "memoryMbytes": 2048, "timeoutSecs": 3600 }
  }'
StatusTypeMeaning
400invalid-inputactId missing, both name and title missing, name over 30 characters, or options.memoryMbytes not a power of two.
400actor-not-builtYour Actor has no successful build yet.
400actor-not-availableSomeone else's Actor can't be run right now.
400input-too-largeThe input is over 9 MB.
403forbiddenPrivate Actor you don't own.
403limit-reachedYou have as many tasks as your plan allows.
404actor-not-foundUnknown Actor.
409task-name-existsYou already have a task with this name.

Get task

GET/v2/actor-tasks/{taskId}
.json
{
  "data": {
    "id": "tAsKiDeXaMpLe123",
    "userId": "uSeRiDeXaMpLe123",
    "actId": "eLN5rTB8sYTBWdfzx",
    "name": "daily-scrape",
    "title": "Daily scrape",
    "input": { "url": "https://example.com" },
    "options": { "memoryMbytes": 2048, "timeoutSecs": 3600 },
    "createdAt": "2026-08-14T15:00:00.000Z",
    "modifiedAt": "2026-08-14T15:00:00.000Z",
    "stats": { "totalRuns": 12 },
    "isPublic": false,
    "publicSlug": null,
    "seoTitle": null,
    "seoDescription": null,
    "useCase": null,
    "publishedAt": null,
    "isDefault": true,
    "lastUsedAt": "2026-08-20T09:00:00Z"
  }
}

isDefault and lastUsedAt (when a run of the task last started, or null) are Scrape.ly additions; list items carry them too, plus title.

GET/v2/actor-tasks/{taskId}

Update task

PUT/v2/actor-tasks/{taskId}

Send any of name, title, input, options, seoTitle, seoDescription, and isDefault. The same name and memory rules as create apply.

While a task is published, its input cannot change: an input edit returns 409 task-published-input-immutable. Unpublish the task, edit it, then publish it again.

.bash
curl -X PUT https://api.scrape.ly/v2/actor-tasks/tAsKiDeXaMpLe123 \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Nightly scrape", "input": { "url": "https://example.com/v2" }}'

Delete task

DELETE/v2/actor-tasks/{taskId}

Returns 204 No Content.

.bash
curl -X DELETE https://api.scrape.ly/v2/actor-tasks/tAsKiDeXaMpLe123 \
  -H "Authorization: Bearer $SCRAPELY_TOKEN"

Task input

GET/v2/actor-tasks/{taskId}/input
PUT/v2/actor-tasks/{taskId}/input

GET returns the saved input as raw JSON, not wrapped in data ({} if there is none). PUT replaces it; the body is the input object (9 MB limit, else 400 input-too-large). The response is the stored input object.

.bash
curl -X PUT https://api.scrape.ly/v2/actor-tasks/tAsKiDeXaMpLe123/input \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "maxResults": 100}'
GET/v2/actor-tasks/{taskId}/input

List task runs

GET/v2/actor-tasks/{taskId}/runs
Query paramDescription
statusFilter by a single run status (TIMED-OUT with a hyphen).
limit / offset / descPagination. Default limit is 1000; desc defaults to newest first.

Each run item also carries taskName.

GET/v2/actor-tasks/{taskId}/runs?limit=5

Run task

POST/v2/actor-tasks/{taskId}/runs

Starts a run with the task's saved input. A non-empty JSON body is merged over the saved input, field by field at the top level (send input fields, not { "input": ... }). A webhooks key in the body is read as ad-hoc webhooks and is not added to the input.

Returns 201 with the run object and a Location header.

Query paramDescription
buildA build ID, tag, version (such as 0.1), or build number (overrides the task options). A tag or version picks the newest matching build; builds started in the same second go to the higher build number. Ignored on someone else's Actor, which always runs the User Build.
memoryMemory in MB, a power of two.
timeoutTimeout in seconds.
maxItemsMax dataset items.
maxTotalChargeUsdMax pay-per-event charge.
restartOnErrorRestart on error.
waitForFinishSeconds to wait for a terminal status (up to 60; the wait stops at 45 seconds, see Waiting for runs and builds).
idempotencyKeySame as the Idempotency-Key header.
forcePermissionLevelLIMITED_PERMISSIONS or FULL_PERMISSIONS. An invalid value returns 400 invalid-force-permission-level.
webhooksBase64-encoded ad-hoc webhook array.

Unset options fall back to the task's options, then the Actor's defaults, then latest, 2048 MB, and 3600 seconds.

.bash
curl -X POST "https://api.scrape.ly/v2/actor-tasks/tAsKiDeXaMpLe123/runs?waitForFinish=30" \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"maxResults": 20}'

Starting a task run can fail with the same errors as Start a run, including 429 concurrency-limit-exceeded and 403 full-permission-actor-not-approved (see Permission approvals).

To make retries safe, send an Idempotency-Key header (or the idempotencyKey query parameter). A repeat with the same key returns 201 with the original run at once and ignores waitForFinish. While the first request is still starting the run, a repeat gets 409 idempotency-key-in-progress; a key already used for a different request returns 422 idempotency-key-reused. See Idempotent run starts.

Run task synchronously

POST/v2/actor-tasks/{taskId}/run-sync
GET/v2/actor-tasks/{taskId}/run-sync

Starts a task run and waits for it to finish. On success, returns the OUTPUT key-value record as raw JSON with status 201, not the run object and not a data envelope.

  • POST merges the body over the saved task input. GET uses the saved input only.
  • outputRecordKey selects a different key-value store record (default OUTPUT).
  • Query parameters: build (owner only, see above), memory, timeout, maxItems, forcePermissionLevel, and webhooks (base64 only; a body webhooks key is not read here). maxTotalChargeUsd and restartOnError come from the task's options.
  • timeout sets the run's timeout. The request waits for timeout seconds or 45 seconds, whichever is shorter. Without timeout, the run keeps the task's timeout and may continue after the request gives up.
StatusTypeMeaning
201—The run succeeded. The body is the output record.
400run-failedThe run ended in a status other than SUCCEEDED.
404record-not-foundThe run succeeded but the output record doesn't exist.
408request-timeoutThe run didn't finish in time. It keeps going; the message includes the run ID so you can keep polling it.

These status codes differ from the Actor endpoints, which return 200, {} for a missing record, and 408 run-timeout-exceeded.

On a 408, wait for the run with GET /v2/actor-runs/{runId}?waitForFinish=60 instead of calling run-sync again, which starts another run.

.bash
curl -X POST https://api.scrape.ly/v2/actor-tasks/tAsKiDeXaMpLe123/run-sync \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

Get dataset items synchronously

POST/v2/actor-tasks/{taskId}/run-sync-get-dataset-items
GET/v2/actor-tasks/{taskId}/run-sync-get-dataset-items

Same wait rules as run-sync. On success, returns the run's dataset items with status 201. It accepts every Get dataset items parameter (format, fields, offset, limit, desc, and so on) and sends the X-Apify-Pagination-* headers.

Last task run

GET/v2/actor-tasks/{taskId}/runs/last

The most recent run of the task. Optional status and waitForFinish (up to 60; the wait stops at 45 seconds). If there's no matching run, returns 404 run-not-found.

Last-run storage shortcuts

Every shortcut accepts status and waitForFinish.

EndpointDescription
GET /v2/actor-tasks/{taskId}/runs/last/logPlain-text log.
GET /v2/actor-tasks/{taskId}/runs/last/datasetDefault dataset.
GET /v2/actor-tasks/{taskId}/runs/last/dataset/itemsDataset items. Takes every Get dataset items parameter.
GET /v2/actor-tasks/{taskId}/runs/last/key-value-storeDefault key-value store.
GET /v2/actor-tasks/{taskId}/runs/last/key-value-store/keysList keys (limit, default 1000, and exclusiveStartKey).
GET /v2/actor-tasks/{taskId}/runs/last/key-value-store/records/{recordKey}Get a record (OUTPUT for named output), or 404 record-not-found.
GET /v2/actor-tasks/{taskId}/runs/last/request-queueDefault request queue.
GET /v2/actor-tasks/{taskId}/runs/last/request-queue/requestsList requests (limit, default 1000, and offset).
GET /v2/actor-tasks/{taskId}/runs/last/request-queue/headQueue head (limit, default 100).
.bash
curl -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  "https://api.scrape.ly/v2/actor-tasks/tAsKiDeXaMpLe123/runs/last/key-value-store/records/OUTPUT?status=SUCCEEDED"
GET/v2/actor-tasks/{taskId}/runs/last

Run objects, abort, resurrect, and logs for a known runId are documented under Actor runs.

Publish a task

POST/v2/actor-tasks/{taskId}/publish
POST/v2/actor-tasks/{taskId}/unpublish

Publishing turns a task into a public example for its Actor. The example gets its own page in the Store, under the Actor's Examples tab, showing the task's input. Values of input fields the Actor's schema marks as secret are masked on that page.

You can publish a task when:

  • you own both the task and the Actor,
  • the Actor is public, not deprecated, and has a successful build,
  • the task input is a non-empty object, and
  • the User Build has a valid input schema (the default build when none is set).

The Actor can have up to 50 published tasks.

Optional publish body fields:

FieldTypeDescription
slugstringURL slug for the example page. Normalized to lowercase letters, digits, and hyphens; must keep at least one letter or digit. Defaults to the slug from the last publish, or one based on the task title or name.
seoTitlestringPage title (max 255 characters).
seoDescriptionstringPage description (max 5000 characters).
useCasestringShort use-case label (max 100 characters).

Both endpoints return the task under data. Unpublishing keeps the SEO fields, so you can publish again later. If you change the slug, the old slug redirects to the new one.

StatusTypeMeaning
400invalid-inputA field is too long, or the slug has no letters or digits.
400actor-not-published / actor-deprecated / actor-not-builtThe Actor doesn't meet the requirements.
400task-input-incompleteThe task input is empty.
400input-schema-missing / input-schema-invalidThe User Build (or the default build when none is set) has no usable input schema.
403forbiddenYou don't own the task or the Actor.
403publish-limit-reachedThe Actor already has 50 published tasks.

Duplicate a task

POST/v2/actor-tasks/{taskId}/duplicate

Copies a task into your account, with its input and options. You can duplicate your own tasks and other users' published examples. When you copy someone else's example, secret input fields are left out of the copy. The new task gets a free name based on the original.

Returns 201 with the new task and a Location header. If you are at your task limit, returns 403 limit-reached.

Task webhooks

GET/v2/actor-tasks/{taskId}/webhooks

Lists your webhooks whose condition names this task. See List webhooks of a task. To find the automations that use a saved input, call GET /v2/automations?savedInputId={taskId} (see Automations API).

Public example tasks

GET/v2/acts/{actorId}/examples
GET/v2/acts/{actorId}/examples/{slug}
GET/v2/acts/{actorId}/examples/{slug}.md

Read the published examples of a public Actor. No authentication. {actorId} must be the Actor ID here, not username~name.

  • The list returns { "data": { "total", "count", "items": [...] } }, newest first. Each item has id, name, title, publicSlug, seoTitle, seoDescription, useCase, publishedAt, actId, actName, actUsername, and actTitle.
  • A single example returns the same fields plus the masked input and duplicateUrl, the duplicate endpoint for that task.
  • The .md variant returns the example as Markdown, which is handy for AI agents.
StatusTypeMeaning
301—The slug changed. Follow the redirect to the current slug.
404example-not-foundNo such example, or the Actor is not public.
410example-goneThe example was unpublished.
GET/v2/acts/{actorId}/examples