Skip to content
JavaScript SDK

Environment

Injected variables, configuration, the Scrape.ly browser, and the API client.

A platform run describes itself through environment variables. This page lists what the platform injects, how the SDK exposes it, how to tune the SDK configuration, how browser crawlers reach the remote browser, and how to get an API client.

Environment and run metadata

Actor.getEnv()

getEnv() reads the environment and returns an object (TypeScript type ApifyEnv, a compatibility name). Missing values are null. It's available as Actor.getEnv() and on instances.

PropertySource
actorIdACTOR_ID
actorRunIdACTOR_RUN_ID
actorTaskIdACTOR_TASK_ID
actorFullNameACTOR_FULL_NAME (owner/actor-name)
actorBuildId, actorBuildNumber, actorBuildTagsACTOR_BUILD_ID, ACTOR_BUILD_NUMBER, ACTOR_BUILD_TAGS (raw strings)
actorEventsWsUrlACTOR_EVENTS_WS_URL, then ACTOR_EVENTS_WEBSOCKET_URL
actorMaxPaidDatasetItemsACTOR_MAX_PAID_DATASET_ITEMS as a number
actorPermissionLevelACTOR_PERMISSION_LEVEL
apiBaseUrlAPIFY_API_BASE_URL, then SCRAPELY_API_URL
apiPublicBaseUrlAPIFY_API_PUBLIC_BASE_URL
tokenAPIFY_TOKEN, then SCRAPELY_TOKEN
isAtHomeAPIFY_IS_AT_HOME, then SCRAPELY_IS_AT_HOME (string, '1' on the platform)
userIdAPIFY_USER_ID
userIsPayingAPIFY_USER_IS_PAYING ('1' or '0')
userPlanSCRAPELY_USER_PLAN ('paid' or 'free')
defaultDatasetId, defaultKeyValueStoreId, defaultRequestQueueIdACTOR_DEFAULT_*_ID
inputKeyACTOR_INPUT_KEY
containerPort, containerUrlACTOR_WEB_SERVER_PORT (number), ACTOR_WEB_SERVER_URL
metaOriginAPIFY_META_ORIGIN, then ACTOR_META_ORIGIN ('STANDBY' for standby runs)
memoryMbytesACTOR_MEMORY_MBYTES as a number
startedAt, timeoutAtACTOR_STARTED_AT, ACTOR_TIMEOUT_AT as Date
maxTotalChargeUsdACTOR_MAX_TOTAL_CHARGE_USD as a number
restartOnErrorACTOR_RESTART_ON_ERROR ('1' or '0')
proxyHostname, proxyPort, proxyPassword, proxyStatusUrlAPIFY_PROXY_*
headless, logLevel, logFormat, localStorageDir, chromeExecutablePathAPIFY_HEADLESS, APIFY_LOG_LEVEL, APIFY_LOG_FORMAT, CRAWLEE_STORAGE_DIR or APIFY_LOCAL_STORAGE_DIR, APIFY_CHROME_EXECUTABLE_PATH

The object also has compatibility fields that Scrape.ly doesn't set (dedicatedCpus, fact, workflowKey, systemInfoIntervalMillis, disableOutdatedWarning, sdkLatestVersion, inputSecretsPrivateKeyFile, inputSecretsPrivateKeyPassphrase).

Variables the platform injects

These are set on every platform run container. Don't set them yourself.

Identity and storage

VariablePurpose
ACTOR_ID / ACTOR_FULL_NAMECurrent Actor ID and owner/actor-name
ACTOR_RUN_IDCurrent run ID
ACTOR_TASK_IDTask that started the run, if any
ACTOR_BUILD_ID / ACTOR_BUILD_NUMBER / ACTOR_BUILD_TAGSBuild this run executes
ACTOR_DEFAULT_DATASET_ID / ACTOR_DEFAULT_KEY_VALUE_STORE_ID / ACTOR_DEFAULT_REQUEST_QUEUE_IDDefault storages
ACTOR_STORAGES_JSONStorage aliases for this run
ACTOR_INPUTRun input as base64-encoded JSON (also stored in the INPUT record)
ACTOR_INPUT_KEYINPUT
ACTOR_METAMORPH_COUNTNumber of metamorphs so far (after a metamorph)

Authentication and API

VariablePurpose
SCRAPELY_TOKEN (also APIFY_TOKEN)Token scoped to this run
SCRAPELY_API_URL (also APIFY_API_BASE_URL)API URL the container uses (internal address)
APIFY_API_PUBLIC_BASE_URLPublic API URL, for links you hand to others
SCRAPELY_IS_AT_HOME (also APIFY_IS_AT_HOME)1 on a platform run
ACTOR_PERMISSION_LEVELLIMITED_PERMISSIONS (default) or FULL_PERMISSIONS
APIFY_USER_IDUser who started the run
APIFY_USER_IS_PAYING / SCRAPELY_USER_PLAN1/paid or 0/free
SCRAPELY_LLM_BASE_URLLLM gateway base URL (OpenRouter-compatible, ends in /v2/llm/api/v1). Use SCRAPELY_TOKEN as the API key

Runtime

VariablePurpose
CDP_URLScrape.ly browser endpoint. Set on every run; used for launches only when the Actor's browser setting is on
ACTOR_EVENTS_WEBSOCKET_URLPlatform events (persistState, migrating, aborting, systemInfo, cpuInfo)
ACTOR_WEB_SERVER_PORT / ACTOR_WEB_SERVER_URLPort your HTTP server listens on (4321) and the URL the platform proxies to it
ACTOR_META_ORIGIN (also APIFY_META_ORIGIN)STANDBY for standby runs
ACTOR_STANDBY_URL / ACTOR_STANDBY_IDLE_TIMEOUT_SECSStandby runs only
ACTOR_STARTED_AT / ACTOR_TIMEOUT_ATISO timestamps
ACTOR_MEMORY_MBYTES / CRAWLEE_MEMORY_MBYTESMemory allocation
ACTOR_RESTART_ON_ERROR1 if the run restarts once after failing
APIFY_HEADLESS1
SCRAPELY_PROXY_* (also APIFY_PROXY_*)Platform proxy credentials; see Proxy configuration
SCRAPELY_BROWSER_PATCH0 when the build has Use Scrapely browser off (the default), so browsers launch in the container

Pricing

VariablePurpose
ACTOR_MAX_TOTAL_CHARGE_USDRun spending cap
ACTOR_MAX_PAID_DATASET_ITEMSResult cap (maxItems)
APIFY_ACTOR_PRICING_INFO (also ACTOR_PRICING_INFO)Pricing as JSON
APIFY_CHARGED_ACTOR_EVENT_COUNTS (also ACTOR_CHARGED_EVENT_COUNTS)Events already charged in this run

Environment variables defined in your Actor's version settings or environmentVariables in the Actor config are added too. Secret inputs are decrypted on the host before the container starts; the platform doesn't provide the APIFY_INPUT_SECRETS_PRIVATE_KEY_* variables.

Convenience properties

These are static getters on Actor:

GetterTypeSource
Actor.fullNamestring | undefinedACTOR_FULL_NAME
Actor.taskIdstring | undefinedACTOR_TASK_ID
Actor.buildIdstring | undefinedACTOR_BUILD_ID
Actor.buildNumberstring | undefinedACTOR_BUILD_NUMBER
Actor.buildTagsstring[]ACTOR_BUILD_TAGS, split on commas
Actor.startedAtstring | undefinedACTOR_STARTED_AT
Actor.timeoutAtstring | undefinedACTOR_TIMEOUT_AT
Actor.tokenstring | undefinedConfigured token
Actor.userIdstring | undefinedAPIFY_USER_ID
Actor.isPayingbooleanAPIFY_USER_IS_PAYING
Actor.apiPublicBaseUrlstring | undefinedAPIFY_API_PUBLIC_BASE_URL
.ts
const msLeft = Actor.getRemainingTime();
if (msLeft !== undefined && msLeft < 30_000) {
    await Actor.exit('Stopping before the timeout');
}
const custom = Actor.getenv('MY_SETTING');

Actor.getRemainingTime() returns milliseconds until ACTOR_TIMEOUT_AT (never below 0), or undefined when there's no timeout. Actor.getenv(key) returns process.env[key]. Actor.isAtHome() is true on a platform run.

Web server and standby metadata

There are no dedicated getters for the web server. Read the values from the configuration:

.ts
const port = Actor.config.get('containerPort');   // ACTOR_WEB_SERVER_PORT, default 4321
const url = Actor.config.get('containerUrl');     // ACTOR_WEB_SERVER_URL
const standbyUrl = Actor.config.get('standbyUrl'); // ACTOR_STANDBY_URL
const isStandby = Actor.isStandby();               // metaOrigin === 'STANDBY'

The SDK doesn't start an HTTP server; your code listens on containerPort. See Standby mode.

Configuration

Configuration extends Crawlee's configuration with Scrape.ly fields. Actor.init() builds it from the environment; most Actors never touch it.

.ts
import { Actor } from 'scrapely';

const token = Actor.config.get('token');
Actor.config.set('persistStateIntervalMillis', 30_000);

To set values before the SDK reads them, pass configuration to Actor.init() or Actor.main() (a matching environment variable still takes precedence):

.ts
await Actor.main(async () => { /* ... */ }, {
    configuration: { persistStateIntervalMillis: 30_000 },
});
MemberPurpose
get(key, defaultValue?)Read a value
set(key, value)Override a value at runtime
getStorageClient() / useStorageClient(client)Read or replace the storage client
getEventManager() / useEventManager(events)Read or replace the event manager
Configuration.getGlobalConfig()The process-wide instance
Configuration.resetGlobalState()Reset the process-wide instance

Scrape.ly fields and their environment variables:

FieldEnvironmentDefault
tokenSCRAPELY_TOKEN, APIFY_TOKEN—
apiBaseUrlSCRAPELY_API_URL, APIFY_API_BASE_URLNon-production URL. Set to https://api.scrape.ly
apiPublicBaseUrlAPIFY_API_PUBLIC_BASE_URLNon-production URL. Set to https://api.scrape.ly
isAtHomeSCRAPELY_IS_AT_HOME, APIFY_IS_AT_HOME—
actorId, actorRunId, actorTaskIdACTOR_ID, ACTOR_RUN_ID, ACTOR_TASK_ID—
actorEventsWsUrlACTOR_EVENTS_WEBSOCKET_URL, APIFY_ACTOR_EVENTS_WS_URL—
containerPort, containerUrlACTOR_WEB_SERVER_PORT, ACTOR_WEB_SERVER_URL4321, http://localhost:4321
standbyUrlACTOR_STANDBY_URL—
standbyPortACTOR_STANDBY_PORT (deprecated; use containerPort)4321
metaOriginACTOR_META_ORIGIN, APIFY_META_ORIGIN—
inputKeyACTOR_INPUT_KEYINPUT
persistStateIntervalMillisCRAWLEE_PERSIST_STATE_INTERVAL_MILLIS60000
maxTotalChargeUsdACTOR_MAX_TOTAL_CHARGE_USD—
testPayPerEvent, useChargingLogDatasetACTOR_TEST_PAY_PER_EVENT, ACTOR_USE_CHARGING_LOG_DATASETfalse
actorStoragesJsonACTOR_STORAGES_JSON—
actorPermissionLevelACTOR_PERMISSION_LEVEL—
userId, userIsPayingAPIFY_USER_ID, APIFY_USER_IS_PAYING—

An environment variable that is set wins over a value passed in configuration or set with set(); defaults apply last. When several variables map to one field, they carry the same value on the platform. Crawlers use the global configuration by default; pass Actor.config as the second constructor argument only if you created a separate Actor instance:

.ts
const crawler = new CheerioCrawler({ /* ... */ }, Actor.config);

Browsers and remote CDP

Where a browser runs depends on the Actor's Use Scrapely browser setting, which is off by default and applied per build. See Scrape.ly Browser.

SituationWhat happens
Setting off (SCRAPELY_BROWSER_PATCH=0)Normal launch in the container, from the browsers in your image
Setting on, on the platformPlaywright calls chromium.connectOverCDP(CDP_URL); Puppeteer calls connect({ browserWSEndpoint })
Setting on, Firefox, WebKit, or Camoufox launcherRedirected to the Scrape.ly browser (Chromium)
Setting on, no CDP URLThrows cdpUrl is required. Local browser launch is disabled — all runs must use the remote browser.
Local run, no CDP URLNormal local launch

Importing the SDK patches Crawlee's browser pool and the Playwright and Puppeteer launchers. The scrapely/actor-node* images also preload the patch through NODE_OPTIONS, so Actors that don't import the SDK are covered.

CDP_URL is set on every run, whatever the setting. setCdpUrl(url) overrides it and setCdpUrl(undefined) clears the override. Call it before the first browser launches, for example to point a local run at a CDP endpoint you host:

.ts
import { Actor, PlaywrightCrawler, setCdpUrl } from 'scrapely';

setCdpUrl('wss://browser.example.com/devtools?token=...');

const crawler = new PlaywrightCrawler({
    async requestHandler({ page }) {
        await Actor.pushData({ title: await page.title() });
    },
});

The Scrape.ly browser has its own exit IP and ignores your proxy URLs. Choose its location with createBrowserConfiguration().

Instance API and API client

Instance API

The class can be instantiated for code that expects an Actor object:

.ts
const actor = new Actor();
await actor.init();
const input = await actor.getInputOrThrow<{ url: string }>();
await actor.pushData({ url: input.url });
await actor.exit({ exit: false });

new Actor(options?) takes ConfigurationOptions. Without options it uses the global configuration. The first instance created becomes the default instance that the static methods use; Actor.getDefaultInstance() returns it.

Instances have the lifecycle, input, storage, status, proxy, browser, state, reboot, metamorph, abort, webhook, call, charging, getEnv(), isAtHome(), and isStandby() methods, plus actor.config and actor.apifyClient. These are static only: the run metadata getters, Actor.events, Actor.input, Actor.getenv(), Actor.getRemainingTime(), and Actor.utils.

API client

Actor.apifyClient and Actor.newClient() return an ApifyClient from scrapely-client, the Scrape.ly JavaScript API client. The name is kept so existing code works; it's the same class as ScrapelyClient. See JavaScript client for its full API.

.ts
const client = Actor.newClient();
const actorInfo = await client.actor('owner~name').get();

const other = Actor.newClient({ token: process.env.OTHER_TOKEN });
CallClient
Actor.apifyClient / Actor.newClient()Shared client with the run's token and SCRAPELY_API_URL
Actor.newClient({ token, baseUrl })New client with that token and/or base URL

The run's client uses the internal API URL for requests and APIFY_API_PUBLIC_BASE_URL for public links such as getRecordPublicUrl(). On pay-per-event Actors it also charges for writes to the default dataset (see Default dataset item event).

ApifyClient, ApifyClientOptions, and ActorRun are re-exported from the SDK root.