Skip to main content

Executors

Executors in Scheduler0 define where and how your scheduled jobs will be executed. They provide the execution environment and infrastructure needed to run your jobs, supporting webhooks, cloud functions, and local shell command execution.

Overview

Executors act as the bridge between Scheduler0's scheduling system and your actual job execution infrastructure. They define the target environment, authentication details, and execution parameters needed to run your jobs successfully.

TypeWhere jobs runRequires network?
webhook_urlRemote HTTP endpointYes
cloud_functionAWS Lambda / Azure Functions / GCPYes
localShell command on your own machineNo (pulls on reconnect)

Executor Structure

{
"id": 1,
"accountId": 123,
"name": "Production Webhook Executor",
"type": "webhook_url",
"cloudProvider": null,
"region": null,
"cloudResourceUrl": null,
"webhookUrl": "https://api.example.com/webhook",
"webhookMethod": "POST",
"webhookSecret": "secret_key_123",
"cloudApiKey": null,
"cloudApiSecret": null,
"command": null,
"workingDir": null,
"dateCreated": "2024-01-15T10:30:00Z",
"dateModified": null,
"createdBy": "user123",
"modifiedBy": null,
"deletedBy": null
}

Fields

  • id: Unique identifier for the executor
  • accountId: ID of the account that owns this executor
  • name: Human-readable name for the executor
  • type: Type of executor (webhook_url, cloud_function, local)
  • cloudProvider: Cloud provider for cloud function executors (aws, azure, gcp)
  • region: Cloud region where the executor is located
  • cloudResourceUrl: URL or identifier of the cloud resource
  • webhookUrl: URL for webhook-based execution
  • webhookMethod: HTTP method for webhook calls (GET, POST, PUT, DELETE)
  • webhookSecret: Secret key for webhook authentication
  • cloudApiKey: API key for cloud provider authentication
  • cloudApiSecret: API secret for cloud provider authentication
  • command: Shell command executed for each job trigger (local executors only)
  • workingDir: Working directory from which the command is run (local executors only, optional)
  • dateCreated: Timestamp when the executor was created
  • dateModified: Timestamp when the executor was last modified
  • createdBy: Identifier of the user who created the executor
  • modifiedBy: Identifier of the user who last modified the executor
  • deletedBy: Identifier of the user who deleted the executor

Executor Types

1. Webhook URL Executor

Webhook executors send HTTP requests to specified URLs when jobs are triggered.

Configuration

{
"name": "API Webhook Executor",
"type": "webhook_url",
"webhookUrl": "https://api.example.com/webhook",
"webhookMethod": "POST",
"webhookSecret": "your_secret_key"
}

Use Cases

  • REST API endpoints
  • Microservice endpoints
  • Third-party service integrations
  • Custom application endpoints

Request Payload

When a job is executed, the webhook executor sends the complete job object as the request payload:

{
"id": 123,
"projectId": 456,
"executorId": 789,
"spec": "0 2 * * *",
"data": "{\"action\": \"process_data\", \"target\": \"database\"}",
"startDate": "2024-01-15T00:00:00Z",
"endDate": "2024-12-31T23:59:59Z",
"retryMax": 3,
"timezone": "UTC",
"timezoneOffset": 0,
"status": "active",
"executionId": "abc123",
"accountId": 1,
"dateCreated": "2024-01-15T10:30:00Z"
}

The data field contains the job-specific data as a JSON string, which you can parse in your webhook handler.

2. Cloud Function Executor

Cloud function executors invoke serverless functions on cloud platforms.

AWS Lambda

{
"name": "AWS Lambda Executor",
"type": "cloud_function",
"cloudProvider": "aws",
"region": "us-east-1",
"cloudResourceUrl": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
"cloudApiKey": "AKIAIOSFODNN7EXAMPLE",
"cloudApiSecret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

Azure Functions

{
"name": "Azure Function Executor",
"type": "cloud_function",
"cloudProvider": "azure",
"cloudResourceUrl": "https://myfunctionapp.azurewebsites.net/api/myfunction",
"cloudApiKey": "your_function_key"
}

Google Cloud Functions

{
"name": "GCP Function Executor",
"type": "cloud_function",
"cloudProvider": "gcp",
"region": "us-central1",
"cloudResourceUrl": "https://us-central1-myproject.cloudfunctions.net/myfunction",
"cloudApiKey": "your_service_account_key"
}

3. Local Executor

Local executors run jobs as shell commands on a machine you control — no public endpoint required. The scheduler0-cli process running on that machine pulls job definitions from the server periodically, executes them locally via os/exec, and batches execution logs back to the server when connectivity is available.

This is ideal for:

  • Jobs that access private databases or internal APIs not reachable from the internet
  • Environments with intermittent connectivity (edge, on-prem, developer machines)
  • Running scripts alongside existing local processes

How it works

┌───────────────────┐         pull jobs (every 1 min)          ┌─────────────────────┐
│ scheduler0-cli │ ─────────────────────────────────────────► scheduler0 API │
│ (your machine) │ ◄───────────────────────────────────────── (sends job list) │
│ │ └─────────────────────┘
│ ┌─────────────┐ │ batch report logs (every 5 min or
│ │ SQLite DB │ │ when 50+ uncommitted logs accumulate)
│ │ jobs cache │ │ ─────────────────────────────────────────►
│ │ exec logs │ │
│ └─────────────┘ │
│ │
│ runs: command │
│ workingDir │
└───────────────────┘
  1. You register a local executor in the dashboard (or via CLI) — this stores a command and optional workingDir server-side.
  2. You create a credential with read, write, and execute scopes, and start the CLI service with it.
  3. The CLI pulls jobs assigned to this executor every minute, maintains a local SQLite cache, and runs each job's trigger time using an internal priority-queue scheduler (same algorithm as the server).
  4. Executions are written to a local executions_uncommitted table; the CLI batch-reports them back to the server on a hybrid schedule: every 5 minutes or whenever 50+ uncommitted logs accumulate, whichever comes first.
  5. The CLI continues executing jobs even when the server is unreachable. Logs are flushed once connectivity is restored.

Configuration

{
"name": "My Local Executor",
"type": "local",
"command": "/usr/local/bin/process-job.sh",
"workingDir": "/home/deploy/myapp"
}
FieldRequiredDescription
commandYesShell command to run for every job trigger
workingDirNoDirectory from which the command is invoked

Job data passed to the command

The CLI writes the job's JSON object to the command's stdin and also exposes key fields as environment variables:

VariableValue
SCHEDULER0_JOB_IDJob ID
SCHEDULER0_EXECUTION_IDUnique execution identifier
SCHEDULER0_JOB_DATARaw contents of the job's data field
SCHEDULER0_JOB_SPECCron spec

Getting started

See the CLI — Local Executor commands for the full setup walkthrough.

Payload Format

All executors (webhooks, AWS Lambda, Azure Functions, and GCP Functions) receive the complete job object as their payload. Here's what the job object looks like:

{
"id": 123,
"projectId": 456,
"executorId": 789,
"spec": "0 2 * * *",
"data": "{\"action\": \"process_data\", \"target\": \"database\"}",
"startDate": "2024-01-15T00:00:00Z",
"endDate": "2024-12-31T23:59:59Z",
"retryMax": 3,
"timezone": "UTC",
"timezoneOffset": 0,
"status": "active",
"executionId": "abc123...",
"accountId": 1,
"dateCreated": "2024-01-15T10:30:00Z",
"createdBy": "user123"
}

Note: The data field contains job-specific data as a JSON-encoded string. Parse it in your handler to access your custom job data.

Creating Executors

Webhook Executor

curl -X POST "https://api.scheduler0.com/v1/executors" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Secret-Key: YOUR_API_SECRET" \
-d '{
"name": "Production API Executor",
"type": "webhook_url",
"webhookUrl": "https://api.example.com/webhook",
"webhookMethod": "POST",
"webhookSecret": "secret_key_123",
"createdBy": "user123"
}'

Node.js Client Example

const Scheduler0Client = require('@scheduler0/node-client');

const client = new Scheduler0Client({
apiKey: 'your_api_key',
apiSecret: 'your_secret_key',
baseURL: 'https://api.scheduler0.com/v1'
});

// Create a webhook executor
const executor = await client.executors.create({
name: "Production API Executor",
type: "webhook_url",
webhookUrl: "https://api.example.com/webhook",
webhookMethod: "POST",
webhookSecret: "secret_key_123",
createdBy: "user123"
});

console.log('Created executor:', executor.data);

AWS Lambda Executor

curl -X POST "https://api.scheduler0.com/v1/executors" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Secret-Key: YOUR_API_SECRET" \
-d '{
"name": "Data Processing Lambda",
"type": "cloud_function",
"cloudProvider": "aws",
"region": "us-east-1",
"cloudResourceUrl": "arn:aws:lambda:us-east-1:123456789012:function:data-processor",
"cloudApiKey": "AKIAIOSFODNN7EXAMPLE",
"cloudApiSecret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"createdBy": "user123"
}'

Node.js Client Example

// Create an AWS Lambda executor
const lambdaExecutor = await client.executors.create({
name: "Data Processing Lambda",
type: "cloud_function",
cloudProvider: "aws",
region: "us-east-1",
cloudResourceUrl: "arn:aws:lambda:us-east-1:123456789012:function:data-processor",
cloudApiKey: "AKIAIOSFODNN7EXAMPLE",
cloudApiSecret: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
createdBy: "user123"
});

console.log('Created Lambda executor:', lambdaExecutor.data);

Local Executor

Local executors are registered through a dedicated endpoint rather than the generic /executors endpoint. The server sets type to local for you, so it is not included in the body.

Endpoint: POST /api/v1/local-executors (scope: write)

Body Fields:

FieldRequiredDescription
nameYesDisplay name for the executor
commandYesShell command run for every job trigger
workingDirNoDirectory the command is invoked from
createdByNoIdentifier of the user creating the executor
curl -X POST "https://api.scheduler0.com/v1/local-executors" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Secret-Key: YOUR_API_SECRET" \
-H "X-Account-ID: YOUR_ACCOUNT_ID" \
-d '{
"name": "My Local Executor",
"command": "/usr/local/bin/process-job.sh",
"workingDir": "/home/deploy/myapp",
"createdBy": "user123"
}'

Response returns the new executor ID:

{
"success": true,
"data": { "id": 42 }
}

After creating the executor, use scheduler0 local-executor register with the returned executor ID (or manage it from the Executors page in the dashboard) and then run scheduler0 local-executor start to begin polling.

CLI-facing endpoints

The scheduler0-cli process uses two additional endpoints. You normally never call these directly — the CLI does — but they are documented here for completeness:

  • GET /api/v1/local-executors/{id}/jobs (scope: read) — returns the active jobs assigned to the local executor. Each call also renews the executor's etcd lease (heartbeat) and records a pull-log entry. Returns 400 if the executor is not of type local.

  • POST /api/v1/local-executors/{id}/executions (scope: execute) — batch-reports execution results. The body is an array of execution events, which are committed via Raft and counted toward the account's execution quota:

    [
    {
    "jobId": 123,
    "uniqueId": "exec-abc123",
    "state": 1,
    "lastExecutionTime": "2024-01-15T10:30:00Z",
    "nextExecutionTime": "2024-01-16T10:30:00Z",
    "executionVersion": 5,
    "jobQueueVersion": 2
    }
    ]

    state is an integer: 0 = scheduled, 1 = success, 2 = failed. The response is { "committed": N }.

Managing Executors

Listing Executors

curl -X GET "https://api.scheduler0.com/v1/executors?limit=10&offset=0" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-API-Secret: YOUR_API_SECRET"

Node.js Client Example

// List all executors
const executors = await client.executors.list(10, 0);
console.log(`Found ${executors.data.length} executors`);

Updating Executors

curl -X PUT "https://api.scheduler0.com/v1/executors/1" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Secret-Key: YOUR_API_SECRET" \
-d '{
"name": "Updated Executor Name",
"webhookUrl": "https://new-api.example.com/webhook",
"modifiedBy": "user123"
}'

Node.js Client Example

// Update an executor
const updatedExecutor = await client.executors.update(1, {
name: "Updated Executor Name",
webhookUrl: "https://new-api.example.com/webhook",
modifiedBy: "user123"
});

console.log('Updated executor:', updatedExecutor.data);

Deleting Executors

curl -X DELETE "https://api.scheduler0.com/v1/executors/1" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Secret-Key: YOUR_API_SECRET" \
-d '{
"deletedBy": "user123"
}'

Node.js Client Example

// Delete an executor
await client.executors.delete(1, {
deletedBy: "user123"
});

console.log('Executor deleted successfully');

API Reference

For complete API documentation, see the Scheduler0 API Reference.