Skip to main content

Using the SDK

There are two ways to get data into Dime.Scheduler via the SDK. Through the low-level import API, or through the direct endpoints.

Initializing the SDK

After installing the SDK, import the namespace where all the functionality lives:

using Dime.Scheduler;
using Dime.Scheduler.Entities;

Now you can easily access the DimeSchedulerClient class. To get started, you only need an API key:

// For production:
DimeSchedulerClient client = new("mykey");

// For sandbox:
DimeSchedulerClient client = new("mykey", Environment.Sandbox);

This object exposes all the endpoints which you can interact with.

API endpoints

By far the easiest approach is to use the direct endpoints. Each entity type has its own dedicated endpoint which you can invoke. For instance, to create a category, one of the visual indicators to render the background color of appointments, this is what you'd need to do:

DimeSchedulerClient client = new("mykey");
await client.Categories.Create(new("Category #1", "#5246CE"));

The import endpoint

Any class that implements the IImportRequestable interface is eligible to be processed by the Dime.Scheduler API. All import requests are done through DimeSchedulerClient's Import property, which is an implementation of the IImportEndpoint interface.


Import types are simple POCOs, decorated by internal mapping and validation information. Behind the covers, these POCOs are translated to a type which the API in Dime.Scheduler can interpret and execute. The API in Dime.Scheduler itself too is a simple and extensible framework which can be customized to your customer's needs.

This example adds or updates a category through the import pipeline:

Category category = new("Category #1", "#5246CE");

DimeSchedulerClient client = new("mykey");
await client.Import.ProcessAsync(category, TransactionType.Append);

This example adds or updates a filter group:

FilterGroup filterGroup = new FilterGroup { Name = "Group 1" };

DimeSchedulerClient client = new("mykey");
await client.Import.ProcessAsync(filterGroup, TransactionType.Append);

As you can see, the experience is exactly the same. The only thing you need to worry about is the (correctness of the) data.


Validation is done through the capabilities exposed in the System.ComponentModel.DataAnnotations namespace. Wrapped in the interface IValidatableImportRequest<out T>, import objects are validated before the request is sent to Dime.Scheduler.

Take the FilterGroup class as an example:

public class FilterGroup : IImportRequestable, IValidatableImportRequest<FilterGroup>
public string Name { get; set; }

public int ColumnNo { get; set; }

When invoking the following request, an exception will be thrown:

FilterGroup model = new FilterGroup { ColumnNo = 1 };
((IImportRequestable) model).ToImportRequest(TransactionType.Append); // Will throw exception

The name wasn't populated and wouldn't be acccepted by the the API anyway. As a result, there are two identical validation rounds: once in the SDK and once in Dime.Scheduler's API.

Supported models and actions

For an up to date list of the types and their properties, check out the source code. All types you can interact with reside in the Dime.Scheduler.Sdk.Models namespace.

Work items

Every task needs to have a job. A job is the equivalent to an order or job in Business Central, while a task would represent service item lines, job tasks. A task is at the lowest level and is the plannable unit of work. The job holds information such as customer information and coordinates, while the task is about the work that needs to be carried out.

Task container
Task filter value
Task locked

The job model is a metadata type that captures information about the work that needs to be done. It contains data about the customer, the shipping and billing address, and more. Thus it does not store information about the actual work itself, which is reserved for the task entity.

A job by itself has not much use as they're not displayed in the open tasks grid until at least one task has been assigned to the job. In almost all cases, a job request will be succeeded by at least one task request.

Because there is so much information stored in the jobs model, a special builder or job factory class was designed. Using a fluent interface, you can construct a job without much fuss:

Job newServiceOrder = new JobBuilder()
.WithJob("BC_CRONUS", "SERVICE", "SO001", "Update HVAC in Berlin office", "Maintain HVAC", "Simon Pecker")
.WithCustomer(new Sdk.Import.Customer
Email = "[email protected]",
Name = "HQ London",
Phone = "123 423 091",
Reference = "REF"
.WithBill(new Site
Email = "[email protected]",
Name = "HQ London",
Phone = "123 423 091",
Address = new Address { FullAddress = "The Shard, Office 1234, London, United Kingdom" }
.WithContact(new Contact
Address = "Kommandantenstraße 18, 10969 Berlin, Germany",
Name = "Contact 1",
No = "CONTACT_001",
Email = "[email protected]",

The produced item is a plain old Job POCO, which can be passed onto the API.


An appointment is merely an assignment of a task to a resource on a given date and time. An appointment is the base entity, and an assignment entity represents the allocation of a resource to an appointment.

Appointment category
Appointment time marker
Appointment importance
Appointment locked
Appointment planning quantity
Appointment URL
Appointment Container


Resource Calendar
Resource Capacity
Resource Filter Value
Resource GPS Tracking
Resource URL

Attributes & Requirements

Filter Group
Filter Value


An indicator is essentially a color representing a certain status. Categories display the background colors of appointments, while time markers render a underscore and pins display the colors of the markers on the map.

Time marker

Other endpoints

Action URI