---
title: "Quick start · Scrape.ly Docs"
description: "Install the CLI, build an Actor from a template, deploy it, and get your first results."
url: https://scrape.ly/docs/quickstart
markdown: https://scrape.ly/docs/quickstart.md
---

# Quick start

> Install the CLI, build an Actor from a template, deploy it, and get your first results.

Go from an empty terminal to an Actor running on Scrape.ly, with results you can download, in about ten minutes. The whole flow:

```bash
npm install -g scrapely-cli
export SCRAPELY_API_URL=https://api.scrape.ly SCRAPELY_WEB_URL=https://my.scrape.ly
scrapely login
scrapely create my-first-actor --template crawlee-cheerio-js && cd my-first-actor
scrapely push
scrapely call -i '{"startUrls":[{"url":"https://crawlee.dev"}],"maxRequestsPerCrawl":10}' -o
```

You write code locally and the platform builds and runs it. The templates build on the Scrape.ly base images (`scrapely/actor-node`, `scrapely/actor-python`), which already contain the SDK, so you don't add it to `package.json` or `requirements.txt`, and you don't need Docker.

| You need | Why |
| --- | --- |
| A [Scrape.ly account](https://my.scrape.ly/register) | To log in |
| Node.js 20.17 or newer | The CLI runs on Node.js |
| Git, with access to GitHub | `scrapely create` clones the template repository |
| npm (JavaScript and TypeScript templates) | `create` runs `npm install` |

## 1. Install the CLI

The CLI is published as `scrapely-cli` and installs the `scrapely` executable.

```bash
npm install -g scrapely-cli
scrapely --version
```

Or skip the global install and use `npx scrapely-cli <command>`.

## 2. Log in

```bash
export SCRAPELY_API_URL=https://api.scrape.ly
export SCRAPELY_WEB_URL=https://my.scrape.ly
scrapely login
scrapely info
```

> [!WARNING]
> Set both variables before your first login, and keep them in your shell profile. Without `SCRAPELY_API_URL` the CLI uses its built-in default API URL, which is not production. `SCRAPELY_WEB_URL` makes the dashboard links the CLI prints point at the dashboard.

On an interactive terminal, `login` asks how to sign in:

| Choice | What happens |
| --- | --- |
| **browser** (recommended) | The CLI opens the dashboard, you approve, and the CLI receives a token on a local callback. Expires after 24 hours by default |
| **console** | Copy an API key from **Settings → API & Integrations** and paste it in |
| **manual** | Paste a key you already have |

The CLI checks the token against `GET /v2/users/me` and saves it to `~/.scrapely/credentials.json`. `scrapely info` shows who you're logged in as. For CI, use an API key. See [Authentication](https://scrape.ly/docs/cli-auth.md).

## 3. Create an Actor from a template

```bash
scrapely create my-first-actor --template crawlee-cheerio-js
cd my-first-actor
```

- The name needs at least three characters: lowercase letters, digits, and hyphens, not starting or ending with a hyphen.
- `create` with no arguments asks for the name, use case, language, and template.
- `create` copies the template into `my-first-actor/`, sets the Actor name in `package.json` and `.actor/scrapely.json`, makes a first Git commit, and runs `npm install`. Skip the last two with `--skip-git-init` and `--skip-dependency-install`.

The templates come from the platform catalog (`scrapely templates ls`); sources are in [scrapely-app/actor-templates](https://github.com/scrapely-app/actor-templates).

| Template | Language | What it does |
| --- | --- | --- |
| `crawlee-cheerio-js` | JavaScript | HTTP crawler that parses HTML with Cheerio. No browser |
| `crawlee-playwright` | JavaScript | Browser crawler with Playwright and Chromium |
| `crawlee-puppeteer-chrome` | JavaScript | Browser crawler with Puppeteer and Chrome |
| `crawlee-playwright-ts` | TypeScript | Browser crawler with Playwright and Chromium |
| `js-bootstrap-cheerio-crawler` | JavaScript | JavaScript minimal site crawler (Crawlee + Cheerio) |
| `js-crawlee-playwright-camoufox` | JavaScript | JavaScript stealth crawler (Crawlee + Playwright + Camoufox) |
| `js-cypress` | JavaScript | JavaScript test runner (Cypress) |
| `js-empty` | JavaScript | Empty JavaScript Actor |
| `js-langchain` | JavaScript | JavaScript website chat (LangChain) |
| `js-langgraph-agent` | JavaScript | JavaScript web search agent (LangGraph) |
| `js-standby` | JavaScript | JavaScript API Actor |
| `js-start` | JavaScript | JavaScript one-page scraper (Cheerio) |
| `ts-beeai-agent` | TypeScript | TypeScript social media agent (BeeAI) |
| `ts-crawlee-cheerio` | TypeScript | TypeScript site crawler (Crawlee + Cheerio) |
| `ts-crawlee-playwright-camoufox` | TypeScript | TypeScript stealth crawler (Crawlee + Playwright + Camoufox) |
| `ts-crawlee-puppeteer-chrome` | TypeScript | TypeScript browser crawler (Crawlee + Puppeteer + Chrome) |
| `ts-empty` | TypeScript | Empty TypeScript Actor |
| `ts-mastraai` | TypeScript | TypeScript social media agent (Mastra) |
| `ts-mcp-empty` | TypeScript | TypeScript MCP server |
| `ts-mcp-proxy` | TypeScript | TypeScript MCP proxy |
| `ts-playwright-test-runner` | TypeScript | TypeScript test runner (Playwright) |
| `ts-standby` | TypeScript | TypeScript API Actor |
| `ts-start` | TypeScript | TypeScript one-page scraper (Cheerio) |
| `ts-start-bun` | TypeScript | TypeScript one-page scraper (Bun + Cheerio) |

`crawlee-playwright-js` and `crawlee-puppeteer-js` still work as aliases for `crawlee-playwright` and `crawlee-puppeteer-chrome`. Browser templates launch Chromium in the container; to offload it, turn on the [Scrape.ly browser](https://scrape.ly/docs/browser.md) for the Actor later.

| Path | Purpose |
| --- | --- |
| `.actor/scrapely.json` | Actor config: name, version, Dockerfile, and the paths to the schemas below |
| `.actor/input_schema.json` | The input the Actor accepts. The dashboard builds its input form from it |
| `.actor/dataset_schema.json`, `.actor/output_schema.json` | How the dashboard displays the results |
| `src/main.js` | Entry point. Reads the input and starts the crawler |
| `src/routes.js` | Request handler that runs for every page |
| `Dockerfile` | Builds on `scrapely/actor-node:24-latest` |
| `package.json` | Dependencies. The SDK isn't listed: the base image provides it |

## 4. Write your Actor

`src/main.js` reads the input, sets up the platform proxy, and runs the crawler. `src/routes.js` handles each page; this version also stores the first heading and the link count:

```js [src/main.js]
import { CheerioCrawler } from '@crawlee/cheerio';
import { Actor } from 'scrapely';

import { router } from './routes.js';

await Actor.init();

const { startUrls = ['https://crawlee.dev'], maxRequestsPerCrawl = 100 } = (await Actor.getInput()) ?? {};

const proxyConfiguration = await Actor.createProxyConfiguration({ checkAccess: true });

const crawler = new CheerioCrawler({
    proxyConfiguration,
    maxRequestsPerCrawl,
    requestHandler: router,
});

await crawler.run(startUrls);

await Actor.exit();
```

```js [src/routes.js]
import { createCheerioRouter } from '@crawlee/cheerio';

export const router = createCheerioRouter();

router.addDefaultHandler(async ({ enqueueLinks, request, $, log, pushData }) => {
    await enqueueLinks();

    const title = $('title').text();
    log.info(title, { url: request.loadedUrl });

    await pushData({
        url: request.loadedUrl,
        title,
        h1: $('h1').first().text().trim(),
        links: $('a[href]').length,
    });
});
```

| Call | Does |
| --- | --- |
| `enqueueLinks()` | Adds links on the same domain to the crawl |
| `pushData()` | Appends one item to the run's default dataset |
| `maxRequestsPerCrawl` | Stops the crawl after that many pages |

> [!TIP]
> When you change the stored fields, update `.actor/dataset_schema.json` too. New input fields go in `.actor/input_schema.json`. Check both with `scrapely validate-schema`.

## 5. Push and build

```bash
scrapely push
```

The first push creates the Actor in your account, uploads the source as version `0.0` with build tag `latest`, writes the Actor ID into `.actor/scrapely.json`, then builds and waits. A failed build prints its log and exits non-zero. Later pushes update the same Actor and always rebuild.

## 6. Run it

```bash
scrapely call -i '{"startUrls":[{"url":"https://crawlee.dev"}],"maxRequestsPerCrawl":10}' -o
```

`call` starts a run on the platform and streams the log until it finishes. `-o` prints the dataset items when it succeeds.

| Input source | Flag |
| --- | --- |
| Inline JSON | `-i '<json>'` |
| A file, or stdin | `-f input.json`, `-f -` |
| None given | `storage/key_value_stores/default/INPUT.json` if it exists, otherwise no input (the Actor uses its defaults) |

> [!WARNING]
> `scrapely run` is a different command. It runs the project on your machine, not on the platform. That needs the Scrape.ly SDK importable in your local environment, which the base images provide but a fresh template project does not. Use `scrapely call` for this guide. See [Projects & running](https://scrape.ly/docs/cli-projects.md#run-locally) for local runs.

## 7. Get the results

```bash
scrapely runs ls --desc          # this Actor's runs, newest first
scrapely runs info <runId>       # shows the run's Dataset ID
scrapely datasets get-items <datasetId> --format csv > results.csv
```

`--format` accepts `json` (default), `jsonl`, `csv`, `html`, `rss`, `xml`, and `xlsx`, written to stdout. To browse the log and dataset in the dashboard, open `https://my.scrape.ly/actors/<actorId>`, or use `scrapely push --open`.

## Next steps

- [Actor development academy](https://scrape.ly/docs/academy.md): a longer, guided course.
- [Actors](https://scrape.ly/docs/actors.md): how builds, versions, runs, input, and output fit together.
- [JavaScript SDK](https://scrape.ly/docs/sdk-node.md) or [Python SDK](https://scrape.ly/docs/sdk-python.md): everything `Actor` can do.
- [Publishing](https://scrape.ly/docs/publishing.md): list the Actor in the Store and set its pricing.
- [CLI reference](https://scrape.ly/docs/cli.md): every command used here, and the rest.

## Troubleshooting

| Problem | Fix |
| --- | --- |
| `scrapely: command not found` | npm's global bin directory isn't on your `PATH`. Add it, or use `npx scrapely-cli` |
| `You are not logged in`, or a 401 | The token is missing or expired (browser tokens last 24 hours by default). Run `scrapely login`. Check `SCRAPELY_API_URL` and `scrapely info` if you hit the wrong API |
| `Directory "my-first-actor" already exists` | Pick another name or remove the folder. `create` never writes into an existing directory |
| `create` can't download the template | It runs `git clone` against GitHub. Install Git and check you can reach `github.com` |
| The build fails | `push` prints the log; see also `scrapely builds log <buildId>`. Often a file is missing from the upload: `push` skips `node_modules`, `.git`, `storage`, `dist`, `.env`, `*.log`, and anything matched by `.gitignore` and `.actorignore` |
| The run fails | `scrapely runs log <runId>`. Check the input matches `.actor/input_schema.json`; in the Cheerio template, `startUrls` is a list of `{ "url": "…" }` objects |

---

- Previous: [Notifications](https://scrape.ly/docs/notifications.md)
- Next: [Learning path](https://scrape.ly/docs/academy.md)
- All docs: [Docs index](https://scrape.ly/docs.md), [llms.txt](https://scrape.ly/llms.txt)
