--- title: "Rocket Chat Scheduler API Guide" slug: "scheduler-api" description: "Use the Scheduler API in Rocket Chat Apps-Engine. Automate secure tasks and enhance collaboration workflows." updated: 2026-02-27T05:34:33Z published: 2026-02-27T05:34:33Z canonical: "developer.rocket.chat/scheduler-api" --- > ## Documentation Index > Fetch the complete documentation index at: https://developer.rocket.chat/llms.txt > Use this file to discover all available pages before exploring further. # Scheduler API The Scheduler API allows apps to create tasks that run in a defined schedule. These tasks can be one-time events or recurring tasks. It uses [agenda.js](https://github.com/agenda/agenda) as the backend, so the [schedule syntax](https://github.com/agenda/human-interval) and internal processes are all according to its documentation. The API details are in the [Module scheduler](https://rocketchat.github.io/Rocket.Chat.Apps-engine/modules/scheduler.html) definition and this [example app](https://github.com/RocketChat/Apps.RocketChat.Tester/tree/scheduler) can also be used as a guide. Check your app logs to see the example in action. ## Add permissions As per the [permission system](/v1/docs/app-permission-system), the scheduler API needs the following permission in your app's manifest (`app.json` file): ```json {  "permissions": [    { "name": "scheduler" }  ] } ``` ## Register jobs (processors) To use the scheduler API, you'll need two things: - The functions to be run as jobs (we call them `processors`). - The schedule in which they run. This is configured using the app's `extendConfiguration` method. The processors are registered during the app's startup to make them available for scheduling. Refer to the following code snippet: ```typescript import { IConfigurationExtend } from '@rocket.chat/apps-engine/definition/accessors'; import { IJobContext } from '@rocket.chat/apps-engine/definition/scheduler'; import { App } from '@rocket.chat/apps-engine/definition/App'; export class MyApp extends App {    public async extendConfiguration(configuration: IConfigurationExtend): Promise {        configuration.scheduler.registerProcessors([            {                id: 'first',                // NOTE: Use a method reference — do NOT use an arrow function or .bind(this)                processor: this.myProcessor,            },        ]);    }    private async myProcessor(jobData: IJobContext): Promise {        this.getLogger().info(`[${ new Date() }] this is a task`, jobData);    } } ``` The `processor` is an `async` function and can receive arguments (`jobData`). The arguments are passed during scheduling. > [!WARNING] > Processor functions are commonly registered as arrow functions. For example, > > ```typescript > processor: async (jobData) => this.getLogger().info(`[${ Date() }] this is a task`, jobData) > ``` > > But this poses a challenge for us to inject the correct app reference to its execution. Arrow functions lexically bind `this` at definition time, which prevents the runtime from injecting the correct request-scoped app proxy during execution. It is recommended that you follow the code examples used in this document. For further details on logging, refer to the [**App Logs**](/v1/docs/app-logs) document. ## Start a job To trigger the registered processor as a job, you must provide: - The `id` of the processor. - The type of job it will be. The available types are `scheduleRecurring` (the job runs in an `interval`) and `scheduleOnce` (the job runs once using the `when` keyword). Starting a job can be done when running a slash command, for example: ```typescript // slashcommand class public async executor(context: SlashCommandContext, read: IRead, modify: IModify): Promise {    // SCHEDULING A RECURRING TASK    const task = {        id: 'first',        interval: '10 seconds',        data: { test: true },    };    await modify.getScheduler().scheduleRecurring(task);    // SCHEDULING ONETIME TASK    const task = {        id: 'first',        when: '8 seconds',    };    await modify.getScheduler().scheduleOnce(task); } ``` You can also trigger a job as soon as it gets registered without manual or automated triggering. When you register your processor in the `extendConfiguration` method, you can pass a prop called `startupSetting` in the processor's object, as follows: ```typescript import { IConfigurationExtend } from '@rocket.chat/apps-engine/definition/accessors'; import { IJobContext, StartupType } from '@rocket.chat/apps-engine/definition/scheduler'; import { App } from '@rocket.chat/apps-engine/definition/App'; export class MyApp extends App {    public async extendConfiguration(configuration: IConfigurationExtend): Promise {        configuration.scheduler.registerProcessors([            {                id: 'first',                // Using a method reference                processor: this.firstProcessor,                startupSetting: {                    type: StartupType.ONETIME,                    when: '20 seconds',                    data: { test: true },                },            },            {                id: 'second',                // Using a method reference                processor: this.secondProcessor,                startupSetting: {                    type: StartupType.RECURRING,                    interval: '20 seconds',                },            },        ]);    }    private async firstProcessor(jobData: IJobContext): Promise {        this.getLogger().info(`[${ new Date() }] first processor ran`, jobData);    }    private async secondProcessor(jobData: IJobContext): Promise {        this.getLogger().info(`[${ new Date() }] second processor ran`, jobData);    } } ``` This indicates that you want that particular processor to be scheduled as soon as it is registered. You can define the "immediate scheduling" as a recurring job ( `StartupType.RECURRING`) or a one-time job ( `StartupType.ONETIME`). You can also pass data using the `data` object. It will work just like when you schedule a task using the `modify` accessor. Here, `data` is not something that's passed to the processor or a function as a living object or executable code. This `data` is a static piece of data that is passed to the processor's first argument. The signature of the processor function is as follows: ```typescript (jobContext: IJobContext, read: IRead, modify: IModify, http: IHttp, persis: IPersistence) => Promise ``` The first argument is the data object you're passing when actually scheduling the job; ( `[k: string]:any`). The rest of the arguments are passed when the function is run. ## Cancel a job To stop a job, all you have to do is pass the ID of the job you want to stop: ```typescript const jobId = 'first'; await modify.getScheduler().cancelJob(jobId); ``` It will stop the running job (if any). ## Cancel all jobs from the app To stop all the current running jobs from the app: ```typescript await modify.getScheduler().cancelAllJobs(); ```