Using the SDK
Creating a client
DimeSchedulerClient is the single entry point. It needs an API key and optionally an environment:
using Dime.Scheduler;
using Dime.Scheduler.Entities;
// Production (default)
var client = new DimeSchedulerClient("MY_API_KEY");
// Sandbox
var client = new DimeSchedulerClient("MY_API_KEY", Environment.Sandbox);
// Custom retry policy
var client = new DimeSchedulerClient("MY_API_KEY", Environment.Sandbox, RetryOptions.Default);
DimeSchedulerClient is thread-safe and meant to be long-lived - instantiate it once at startup (e.g. as a singleton in your DI container) and reuse it.
Domain accessors
Every entity hangs off a typed accessor on the client. The accessor list mirrors the JS and Python SDKs 1:1 - same names, idiomatic casing per language:
client.Categories // /category
client.Appointments // /appointment
client.Jobs // /job
client.Tasks // /task
client.Resources // /resource
client.FilterGroups // /filterGroup
client.FilterValues // /filterValue
client.Messages // /message
client.Notifications // /notification
CRUD-shaped entities expose CreateAsync, UpdateAsync, DeleteAsync, and GetAllAsync<TDto>(). All write methods accept either a single entity or an IEnumerable<T>:
await client.Categories.CreateAsync(new Category { Name = "VIP", Color = "#22d3ee" });
await client.Categories.CreateAsync(new[] { cat1, cat2, cat3 });
await client.Categories.UpdateAsync(category);
await client.Categories.DeleteAsync(category);
Result<ICollection<CategoryDto>> categories = await client.Categories.GetAllAsync<CategoryDto>();
Endpoints with their own shape get purpose-built methods:
await client.Appointments.GetAsync(startDate, endDate, new[] { "R1", "R2" });
await client.Notifications.GetAsync(page: 1, limit: 50, sort: "createdAt:desc");
await client.Messages.PostAsync(new Message { Text = "Heads up!", Severity = Severity.Warning });
await client.Geocoding.GeocodeAsync(address);
await client.Optimization.FieldServiceAsync(request);
For the full accessor list, see DimeSchedulerClient.cs.
Results
Every call returns a Result<T>:
var result = await client.Categories.CreateAsync(category);
result.IsSuccess // bool
result.IsFailure // !IsSuccess
result.Value // the payload on success
result.Error // typed Error on failure
The SDK never throws on a non-2xx - you decide how to react. A typical guard:
var result = await client.Categories.CreateAsync(category);
if (result.IsFailure)
{
logger.LogWarning("Create failed: {Error}", result.Error);
return;
}
Retries
Transient failures retry by default - connection errors, timeouts, and HTTP 408 / 429 / 500 / 502 / 503 / 504. Backoff is exponential with jitter and honours Retry-After.
Override the policy with RetryOptions:
var client = new DimeSchedulerClient(
"MY_API_KEY",
Environment.Production,
new RetryOptions(maxRetries: 5, initialDelay: TimeSpan.FromSeconds(1)));
Pass RetryOptions.Disabled to turn retries off entirely.
Cancellation
Every async method accepts a CancellationToken as the last argument:
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = await client.Imports.RunAsync(payload, cts.Token);
This is on top of the SDK's built-in per-request timeout - use it when you need to abort an in-flight call from the outside (a user closing a UI, a long-running batch job hitting a deadline).