Beginner

Getting Started with Apify Actors

To build an Apify actor, install Node.js 18+ and the Apify CLI, scaffold a project with apify create, write your logic inside Actor.main(), define an input_schema.json, and deploy with apify push. This guide walks through every step from zero to a published Apify Store listing.

By Ryan ClintonLast updated: March 27, 2026

An Apify actor is a serverless program that runs in the cloud. Think of it as a function you deploy once and call via API forever. Actors can scrape websites, process data, send notifications, orchestrate other actors, or expose tools through the Model Context Protocol (MCP). Every actor lives in a Docker container, accepts structured JSON input, and produces output in datasets, key-value stores, or request queues. This guide takes you from zero to a fully deployed, working actor on the Apify Store.

Prerequisites

Before you write your first line of code, you need three things installed locally. First, Node.js version 18 or later. Second, the Apify CLI, which you install globally with npm. Third, an Apify account — the free tier is enough to get started.

# Install the Apify CLI globally
npm install -g apify-cli

# Log in to your Apify account (opens a browser window)
apify login
bash

Once logged in, the CLI stores your API token locally. You can verify your login with apify info, which prints your username, user ID, and token status. If you are managing multiple accounts, you can switch between them by running apify login again with a different token.

Creating a new actor project

The fastest way to start is with the Apify CLI scaffolding command. This generates a complete project structure with all the required files, a working Dockerfile, and a sample input schema.

# Create a new actor from the JavaScript template
apify create my-first-actor --template javascript

# Or use TypeScript if you prefer type safety
apify create my-first-actor --template typescript
bash

Project structure explained

Every actor follows a predictable layout. Understanding each file's purpose will save you hours of debugging later. Here is what the scaffolding creates:

my-first-actor/
  .actor/
    actor.json          # Actor metadata: name, version, Dockerfile path
    input_schema.json   # JSON Schema that generates the Console UI form
    Dockerfile          # Docker build instructions for the runtime
  src/
    main.js             # Your actor's entry point
  package.json          # Node.js dependencies
  README.md             # Store listing content (indexed for search)

The .actor/actor.json file is the single source of truth for how Apify treats your actor. It defines the name, version, build configuration, and pricing model. The input_schema.json generates the UI form in the Apify Console and validates API inputs at runtime. Get this schema right from day one — changing it after users depend on your actor's input structure is painful.

The Actor.main() pattern

Modern Apify actors use the Actor.main() pattern instead of the older Actor.init() / Actor.exit() pair. The main() wrapper handles initialization and cleanup automatically, catches errors, and reports them to the platform. This is the only pattern you should use for new actors.

import { Actor } from 'apify';

Actor.main(async () => {
    // Actor.main() automatically calls Actor.init() before your function
    // and Actor.exit() after it completes (or on error)

    const input = await Actor.getInput();
    const { keyword, maxResults = 100 } = input;

    // Validate input early — fail fast with a clear message
    if (!keyword) {
        throw new Error('The "keyword" input field is required.');
    }

    // Your scraping or processing logic
    const results = await scrapeData(keyword, maxResults);

    // Push results to the default dataset
    await Actor.pushData(results);

    console.log('Done. Pushed ' + results.length + ' results.');
    // Actor.main() calls Actor.exit() automatically here
});
javascript

Common pitfall: Never use Actor.init() and Actor.exit() manually when using Actor.main(). The wrapper handles both calls. If you call Actor.init() inside Actor.main(), the actor initializes twice and may behave unpredictably. If you call Actor.exit() manually, the wrapper's cleanup code may not run.

Common pitfall: Always await asynchronous calls. A common mistake is forgetting to await Actor.pushData(), which causes the actor to exit before data is written. The result: an empty dataset and a confused user.

Input schema in depth

The input schema (.actor/input_schema.json) defines what parameters your actor accepts. It follows JSON Schema with Apify-specific extensions for UI rendering. Every field needs a title, type, and description. The editor property controls which UI component renders in the Console.

{
    "title": "Product Scraper Input",
    "type": "object",
    "schemaVersion": 1,
    "required": ["keyword"],
    "properties": {
        "keyword": {
            "title": "Search keyword",
            "type": "string",
            "description": "The product keyword to search for (e.g., 'wireless headphones')",
            "editor": "textfield"
        },
        "maxResults": {
            "title": "Max results",
            "type": "integer",
            "description": "Maximum number of products to return. Default is 100.",
            "default": 100,
            "minimum": 1,
            "maximum": 10000
        },
        "proxyConfig": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Select proxies to use for scraping",
            "editor": "proxy",
            "default": {
                "useApifyProxy": true,
                "apifyProxyGroups": ["RESIDENTIAL"]
            }
        },
        "outputFormat": {
            "title": "Output format",
            "type": "string",
            "description": "Format for the output data",
            "default": "json",
            "editor": "select",
            "enum": ["json", "csv", "xlsx"],
            "enumTitles": ["JSON", "CSV", "Excel"]
        }
    }
}
json

Tip from managing 250+ actors: Always set sensible defaults for every optional field. Users who run your actor without customizing inputs should get useful results, not errors. The default property in the schema both pre-fills the UI form and is used when the field is omitted from API calls.

Tip: Use the prefill property for example values that show in the UI but are not used as defaults. This helps users understand the expected format without committing to a specific value.

Writing the Dockerfile

The Dockerfile defines the runtime environment for your actor. For most JavaScript and TypeScript actors, the Apify-provided base images handle everything. Do not overcomplicate this file.

FROM apify/actor-node:18

COPY package*.json ./
RUN npm --quiet set progress=false \
    && npm install --omit=dev --omit=optional

COPY . ./

CMD npm start
dockerfile

Common pitfall: Do not install dev dependencies in production builds. The --omit=dev flag keeps your image small and your build fast. A bloated Docker image means slower builds, slower cold starts, and higher compute costs.

Common pitfall: Always copy package*.json and run npm install before copying your source code. Docker caches each layer, so if your source code changes but your dependencies do not, Docker reuses the cached npm install layer. This cuts build times from minutes to seconds.

Testing locally before deploying

Before deploying to the cloud, run your actor locally to catch obvious issues. Create a test input file and use the Apify CLI to run a local test.

# Run the actor locally with a test input file
apify run --input test.json
bash

Check the output in the local storage/ directory that the CLI creates. Look at storage/datasets/default/ for your pushed data. Verify the shape of each record matches what you documented in your README and dataset schema.

Your first deploy

Once your code is ready and tested locally, deploy to Apify with a single command.

# Push your actor to the Apify platform
apify push
bash

This uploads your source code, builds the Docker image on Apify's servers, and makes the actor available via API. After pushing, check the build log in the Apify Console to confirm a clean build. Common build failures include missing dependencies in package.json, incorrect Dockerfile paths in actor.json, and syntax errors that Node.js catches at import time.

After a successful build, your actor is live at https://api.apify.com/v2/acts/YOUR_USERNAME~YOUR_ACTOR/runs. Run it from the Console with your test input to verify everything works in the cloud environment. Pay attention to differences between local and cloud behavior — proxy availability, environment variables, and network access can all differ.

Post-deployment checklist

After your first successful cloud run, complete these steps to make your actor production-ready:

  1. Set categories in actor.json — these determine which Store sections your actor appears in. See the PPE Pricing guide (/learn/ppe-pricing) for details on the pricing model.
  2. Write a complete README — this is your Store listing. See the Store SEO guide (/learn/store-seo) for the recommended structure.
  3. Add a dataset schema — this tells users what output to expect and enables Apify's schema validation. See the Actor Testing guide (/learn/actor-testing) for validation strategies.
  4. Configure PPE pricing if you want to monetize — see the PPE Pricing guide (/learn/ppe-pricing) for pricing strategy.
  5. Run the actor 3-5 times with different inputs to build an initial success rate — Apify's quality score starts tracking from your first run.

Real-world tip: Your first actor will have issues. That is normal. The actors that succeed on the Store are the ones that get iterated on. Deploy early, watch the logs, listen to user feedback, and ship fixes fast. Developers who wait for perfection before deploying never deploy at all.

Related guides

Essential

Apify PPE Pricing Explained: Pay Per Event Model, Strategy, and Code Examples

Pay Per Event (PPE) is Apify's usage-based monetization model for actors on the Apify Store. Developers set a price per event (typically $0.001 to $0.50), call Actor.addChargeForEvent() in their code, and keep 80% of revenue while Apify takes 20%. This ApifyForge guide covers the 80/20 revenue split, actor.json configuration, charging code patterns, the 14-day price change rule, and pricing strategy by actor type.

Revenue

How to Monetize Your Actors

To monetize Apify actors, start with Pay Per Event pricing at $0.01-$0.25 per result, then layer on tiered pricing for power users, free-tier funnels to drive adoption, and MCP server bundles that combine multiple actors into a single subscription. ApifyForge analytics tracks revenue per actor so you know which strategies work. This guide covers each revenue model with real pricing examples.

Quality

Actor Testing Best Practices

To test an Apify actor, define input/output test cases in a JSON fixture, run them with the ApifyForge test runner before every deploy, and set assertions on output shape, field counts, and error rates. The regression suite catches breaking changes by comparing current output against a saved baseline. This guide covers the full testing workflow from local validation to CI/CD integration.

Growth

Store SEO Optimization

Apify Store search ranks actors by title match, README keyword density, category tags, run volume, and a quality score out of 100. To rank higher, write a README that opens with a plain-language description of what the actor does, include target keywords in the first 100 words, set accurate categories in actor.json, and maintain a success rate above 95%. This guide breaks down every ranking factor and shows how ApifyForge tracks your score.

Scale

Managing Multiple Actors

To manage 10, 50, or 200+ Apify actors, use the ApifyForge fleet dashboard to monitor health, revenue, and quality scores across your entire portfolio in one view. Group actors by category, run bulk updates on pricing and metadata, set up failure alerts, and track maintenance pulse to catch stale actors before users complain. This guide covers fleet management workflows at every scale.

Essential

Cost Planning Tools: Calculator, Plan Advisor & Proxy Analyzer

How to use ApifyForge's cost planning tools to estimate actor run costs, choose the right Apify subscription plan, and pick the most cost-effective proxy type for each scraper.

Essential

AI Agent Tools: Pipeline Preflight, LLM Optimizer & Integration Templates

How to use ApifyForge's AI agent tools to debug MCP server connections, design multi-actor pipelines, optimize actor output for LLM token efficiency, and generate integration templates.

Quality

Schema Tools: Diff, Registry & Input Guard

How to use ApifyForge's schema tools to compare actor output schemas, browse the field registry, and test actor inputs before running — preventing wasted credits and broken pipelines.

Essential

Compliance Scanner, Actor Recommender & Comparisons

How to use ApifyForge's compliance risk scanner to assess legal exposure, the actor recommender to find the best tool for your task, and head-to-head comparisons to evaluate competing actors.

Quality

The ApifyForge Testing Suite

Four cloud-powered testing tools for Apify actors: Output Guard, Deploy Guard, Cloud Staging, and Regression Suite. How they work together and when to use each one.

Essential

The Complete ApifyForge Tool Suite

All 15 developer tools in one guide: testing, schema analysis, cost planning, compliance scanning, LLM optimization, pipeline building, and privacy reporting. What each tool does, when to use it, and how they work together.

Beginner

What Is an Apify Actor?

An Apify actor is a serverless cloud program that runs on the Apify platform. It accepts JSON input, executes a task (scraping, data processing, API calls, or AI tool serving), and produces structured output in datasets, key-value stores, or request queues. Actors are packaged as Docker containers and can be run via API, scheduled, or chained together.

Essential

What Are MCP Servers on Apify?

MCP (Model Context Protocol) servers are Apify actors that run in standby mode and expose tools via an HTTP endpoint for AI assistants like Claude Desktop, Cursor, and Windsurf. They connect large language models to real-world data sources -- APIs, databases, web scrapers, and intelligence feeds -- so AI agents can take actions beyond text generation.

Beginner

How to Choose the Right Apify Actor

With over 3,000 actors on the Apify Store, choosing the right one for your task requires evaluating success rates, run history, pricing, maintenance frequency, and input schema quality. This guide provides a decision framework for selecting actors based on measurable quality metrics, plus tools to automate the comparison process.

Scale

How to Manage a Large Apify Actor Portfolio

Managing 10 Apify actors is straightforward. Managing 50 requires dashboards and cost tracking. Managing 200+ demands automated regression testing, schema validation, revenue analytics, and failure alerting. This guide covers the tools, processes, and hard-won lessons from scaling an Apify actor portfolio.