---
title: Scheduling custom tasks
related:
  - https://docs.kentico.com/13/configuring-xperience/scheduling-tasks.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

The process of scheduling a custom task includes:

1. [Configuring your local environment](#configuring-your-local-environment) for scheduled task development
2. [Writing the code](#writing-the-task-code) that performs the required actions
3. [Creating a new scheduled task in the Xperience administration interface](#creating-new-scheduled-tasks)

## Configuring your local environment

Before you start developing scheduled tasks in your local environment, you must configure the scheduler to call the appropriate URLs when processing tasks from the system.

If you locally host the live site and administration applications without using a specific port, follow the steps described in [Domain names for local development](https://docs.kentico.com/13/configuring-xperience/managing-sites/setting-domain-names-for-sites.md#domain-names-for-local-development) to configure either a domain alias or a _Project URL_. However, if the live site or administration applications in your local environment run on specific **ports** (e.g., when launched using IIS Express), you must set the following configuration keys for your applications:

1. Add the following configuration keys to the **web.config** file of the administration application. As the key's values, enter the full local URLs of both the administration and live site application, including the port and virtual directory path (if present):

   ```xml title="Administration application - web.config"

   <appSettings>
       ...
       <!-- Sets the URL for the administration application that gets used by the scheduler -->
       <add key="CMSSchedulerAdministrationUrl" value="http://localhost:3000" />
       <!-- Sets the URL for the live site application that gets used by the scheduler -->
       <add key="CMSSchedulerPresentationUrl" value="http://localhost:5000" />
       ...
   </appSettings>

   ```

   The administration interface needs to have the live site URL available due to the ability to manually launch any scheduled task via the **Scheduled tasks** application.
2. Add the following key to the configuration file in the live site application. As the key's value, enter the full local URL of the live site application, including the port and virtual directory path (if present):

   <!-- dev-model:core start -->

   **ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

   ```js title="Live site application - appsettings.json"

   "CMSSchedulerPresentationUrl": "http://localhost:5000",

   ```

   <!-- dev-model:core end -->

   <!-- dev-model:mvc start -->

   **MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

   ```xml title="Live site application - web.config"

   <add key="CMSSchedulerPresentationUrl" value="http://localhost:5000" />

   ```

   <!-- dev-model:mvc end -->

The scheduler is now configured for local development.

## Writing the task code

You need to define each scheduled task as a class that implements the **CMS.Scheduler.ITask** interface.

Add the class as part of a custom assembly (_Class Library_ project), and include the assembly into the appropriate solution. Depending on where you plan to execute the task, add the assembly to the Xperience administration application, the live site application, or both.

### Preparing a custom assembly

Prepare a separate project for custom classes in your Xperience solution (or use an existing one):

1. Open your Xperience solution in Visual Studio.
2. Create a new _Class Library_ project in the solution.
   - The assembly in the example is named _Custom_, but you can use any other name (e.g. with a unique company prefix).
3. Add the Xperience API libraries to the project:
   1. Right-click the solution in the **Solution Explorer** and select **Manage NuGet Packages for Solution**.
   2. Select the **Kentico.Xperience.Libraries** package.
   3. Install the package into the project (the version must match your MVC project's _Kentico.Xperience.AspNet.Mvc5_ package and the exact hotfix version of your Xperience administration project).
4. Reference the project from the main web application (live site or administration).

### Defining the scheduled task class

1. Create a new class under your custom project. For example, name the class **CustomTask.cs**.
2. Edit the class and add using statements for the following namespaces:

   ```csharp

   using CMS.Core;
   using CMS.Scheduler;


   ```
3. Make the class implement the **ITask** interface.

   ```csharp

   public class CustomTask : ITask

   ```
4. Define the **Execute** method in the class:

   ```csharp

   public class CustomTask : ITask
   {
       /// <summary>
       /// Executes the task.
       /// </summary>
       /// <param name="ti">Info object representing the scheduled task</param>
       public string Execute(TaskInfo ti)
       {
           string details = "Custom scheduled task executed. Task data: " + ti.TaskData;

           // Logs the execution of the task in the event log
           Service.Resolve<IEventLogService>().LogInformation("CustomTask", "Execute", details);

           // Returns a null value to indicate that the task executed successfully
           // Return an error message string with details in cases where the execution fails
           return null;
       }
   }

   ```
5. Save all changes and Rebuild your solution.

You must always include the **Execute** method when writing scheduled tasks. The system calls this method whenever the given task is executed, so it needs to contain all code implementing the required functionality.

In this example, the task only creates a record in the application's [event log](https://docs.kentico.com/13/developing-websites/troubleshooting-websites/working-with-the-system-event-log.md) so that you can confirm it is being executed:

- The **TaskInfo** parameter of the method allows you to access the data fields of the corresponding scheduled task object. The sample code adds the content of the **TaskData** field into the details of the event log entry.
- The string returned by the method is displayed in the administration interface as the result of the task's most recent execution. You can leave it as _null_ in this case.

## Creating new scheduled tasks

1. Sign in to the Xperience administration interface.
2. Open the **Scheduled tasks** application.
3. Select the **Site** for which you wish to schedule the task (or _(global)_ if you want the task to run for all sites or affect global objects)_._
4. Click **New task** and fill in the [properties of the task](https://docs.kentico.com/13/configuring-xperience/scheduling-tasks/reference-scheduled-task-properties.md).

   ![Registering a new custom task](https://docs.kentico.com/docsassets/13/scheduling-custom-tasks/New_Custom_Task.png "Registering a new custom task")
5. Click **Save**.

The system now executes the task regularly according to the specified interval.

## Result

To check the result of this sample custom task, open the **Event log** application and look for entries with _CustomTask_ as the **Source**.

![Information events logged by the custom scheduled task](https://docs.kentico.com/docsassets/13/scheduling-custom-tasks/Custom_Task_Result.png "Information events logged by the custom scheduled task")
