Skip to main content

Actor definition

An actor folder holds your code, a Dockerfile and an .actor/ folder that describes the actor. lantfly push reads .actor/actor.json to create or update the actor and its version.

my-actor/
my-actor/
.actor/
actor.json # the actor definition
input_schema.json # input form and validation
dataset_schema.json # result views in the Console (optional)
output_schema.json # links shown as the run's outputs (optional)
Dockerfile
.dockerignore
src/main.js # or main.py
package.json # or requirements.txt

actor.json​

.actor/actor.json
{
"actorSpecification": 1,
"name": "my-actor",
"title": "My Actor",
"description": "My Actor actor",
"version": "0.1",
"buildTag": "latest",
"input": "./input_schema.json",
"storages": { "dataset": "./dataset_schema.json" },
"dockerfile": "../Dockerfile"
}
FieldRequiredMeaning
actorSpecificationAlways 1.
nameyesThe actor's name in your account: lowercase letters, digits and dashes (^[a-z0-9][a-z0-9-]*$). Its id in the API is <username>~<name>.
titleDisplay name. Default: name.
descriptionOne-line description shown on the actor's page and in the Store.
versionVersion that push creates or updates, as major.minor (for example 0.1). Default 0.1. --version overrides it.
inputThe input schema: a path relative to .actor/, or the schema itself. Without it, push looks for .actor/input_schema.json, then INPUT_SCHEMA.json in the folder.
storages.datasetThe dataset schema: a path relative to .actor/, or the schema itself.
outputThe output schema: a path relative to .actor/, or the schema itself.
dockerfileThe Dockerfile, relative to .actor/ (so ../Dockerfile is the folder's root). Default: Dockerfile in the actor folder.
imageThe image to run, without tag. Default: the actor's current image, or lantfly/<namespace>/<name>.
buildTagWritten by lantfly init; not used by push.

What push sends where:

  • To the actor: name, title, description, image and the input schema.
  • To the version: the input schema, the dataset schema and the output schema. A new version is created with image tag latest and made the default.

The README, categories, example input, default run options and pricing are set on the actor in the Console or with PATCH /api/v3/actors/{actor} (see the API reference).

Dockerfile​

The image is a normal Docker image. Lantfly starts it with its default command, as user 1000:1000, with the run's environment variables. Follow these rules:

  • Run as a non-root user with uid 1000 (USER node in the official Node.js images, or USER 1000:1000).
  • Use an init process such as tini as the entrypoint, so SIGTERM reaches your program and the SDK can flush data before the run stops.
  • Write temporary files to /tmp: the working directory may not be writable. The SDK points Crawlee's local storage to /tmp/crawlee.
  • Keep node_modules, storage and .git out of the build context with .dockerignore.

The Dockerfile from lantfly init:

Dockerfile
FROM node:22-bookworm-slim
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev --no-audit --no-fund
COPY . ./
USER node
CMD ["npm", "start", "--silent"]

A production image for a Crawlee actor, with tini, a fixed time zone and UTF-8:

Dockerfile
FROM node:22-bookworm-slim
ENV NODE_ENV=production LANG=C.UTF-8 LC_ALL=C.UTF-8 CRAWLEE_STORAGE_DIR=/tmp/crawlee
RUN apt-get update \
&& apt-get install -y --no-install-recommends tini ca-certificates procps \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /tmp/crawlee && chown node:node /tmp/crawlee
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev --no-audit --no-fund
COPY . ./
USER node
ENTRYPOINT ["tini", "--"]
CMD ["node", "src/main.js"]
tip

Crawlee's browser pool reads memory with ps. Slim Debian images have none, so install procps for browser crawlers.

Input schema​

.actor/input_schema.json describes the input. The Console builds the run form from it, the platform fills in default values, and the API refuses inputs that do not match it (422). See Input schema.

.actor/input_schema.json
{
"title": "My Actor input",
"type": "object",
"schemaVersion": 1,
"properties": {
"message": { "title": "Message", "type": "string", "description": "Text stored in every item.", "editor": "textfield", "default": "Hello from Lantfly" },
"count": { "title": "Count", "type": "integer", "description": "How many items to push.", "minimum": 1, "maximum": 1000, "default": 3 }
},
"required": []
}

Dataset schema​

.actor/dataset_schema.json tells the Console how to show the results. Each view picks and orders fields and says how to display them.

.actor/dataset_schema.json
{
"actorSpecification": 1,
"fields": {
"type": "object",
"properties": {
"index": { "type": "integer" },
"message": { "type": "string" },
"at": { "type": "string" }
}
},
"views": {
"overview": {
"title": "Overview",
"transformation": { "fields": ["index", "message", "at"] },
"display": {
"component": "table",
"properties": {
"index": { "label": "#", "format": "number" },
"message": { "label": "Message", "format": "text" },
"at": { "label": "At", "format": "date" }
}
}
}
}
}
KeyMeaning
views.<name>.titleName of the view in the Console.
views.<name>.transformation.fieldsFields of the view, in order (required).
views.<name>.transformation.unwind, flatten, omit, descThe same as the dataset items parameters.
views.<name>.display.componenttable.
views.<name>.display.properties.<field>label and format: text, number, date, link, image, boolean, array or object.

The schema is checked when you save the version. A run's views are returned by GET /api/v3/runs/{run}/views, each with the query (dataset item parameters) that applies it. You can also ask for a view directly:

Items of the overview view
curl "https://lantfly.com/api/v3/datasets/<datasetId>/items?view=overview" \
-H "Authorization: Bearer $LANTFLY_TOKEN"

Parameters you pass explicitly win over the view. An unknown view answers 400 invalid_parameter.

Output schema​

.actor/output_schema.json lists links to show as the run's outputs. Each property has a title and a template with placeholders that are filled with /api/v3 URLs of the run:

.actor/output_schema.json
{
"actorSpecification": 1,
"properties": {
"results": {
"title": "Results",
"template": "{{links.apiDefaultDatasetUrl}}/items?view=overview"
},
"summary": {
"title": "Summary",
"template": "{{links.apiDefaultKeyValueStoreUrl}}/records/OUTPUT"
}
}
}

Placeholders include {{links.apiDefaultDatasetUrl}}, {{links.apiDefaultKeyValueStoreUrl}}, {{links.apiRunUrl}} and {{run.id}}. The filled links come back in the outputs of GET /api/v3/runs/{run}/views.

What the actor writes​

WhereWhat
Default datasetOne item per result (Actor.pushData). Error rows from the SDK have an error field.
Default key-value store, INPUTThe input of the run (written by the platform).
Default key-value store, OUTPUTA summary of the run. The SDKs write it at the end of Actor.main with the run status and the outcome of each input.
Default key-value store, other keysAnything else: screenshots, files, state.
Status messageA short line shown on the run (Actor.setStatusMessage).