[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/resource-data/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# ResourceData

One resource in [`ProjectData.Resources`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) or in a [`SchedulingChanges.Resources`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/scheduling-changes.md>)`.Add` list. Assignments reference it by ID through [`AssignmentData.Resource`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/assignment-data.md>). Create it with an object initializer; `Id` is `required`. To change a resource that a project already holds, send a [`ResourceUpdate`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/resource-update.md>) instead.

## Declaration

```csharp
namespace Plen;

public sealed class ResourceData : IDeepCloneable<ResourceData>
```

## Properties

| Property | Type | Default | Description |
|---|---|---|---|
| `Id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>) | required | Resource ID. Unique among the project's resources. |
| `Capacity` | `double?` | `null` | Units the resource can take at once, in the same scale as assignment `Value` (`1` = 100 %). `null` uses [`SchedulingConfig.DefaultResourceCapacity`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/scheduling-config.md#defaultresourcecapacity>). Must be finite and `>= 0`. |
| `CalendarId` | `Id?` | `null` | The resource's working calendar. Read only in [`CalendarMode.Resource`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/calendar-mode.md>), where it must name a calendar in [`ProjectData.Calendars`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md#calendars>). `null` means the resource has no calendar of its own. |

In the `CalendarMode.Task` and `CalendarMode.TaskInherited` modes, `CalendarId` isn't resolved, so it can name a calendar that doesn't exist. How the resource calendar combines with a task calendar is covered in [Resource calendars](<https://docs.dhtmlx.com/planning-engine/net/scheduling/working-time-calendars.md#resource-calendars>). How capacity relates to load and overallocation is covered in [Resources and capacity](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/resources-and-assignments.md#resources-and-capacity>).

## Methods

### DeepClone

```csharp
public ResourceData DeepClone()
```

Returns a copy with the same `Id`, `Capacity` and `CalendarId`.

### ToString

```csharp
public override string ToString()
```

Returns a readable rendering of `Id`, `Capacity` and `CalendarId`, for logging.

## Errors

The call that receives the data throws [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) with `Kind = `[`InputErrorKind.Validation`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md#inputerrorkind>):

| `Path` | When |
|---|---|
| `resources[i].id` | Two resources share an ID (`"duplicate resource id"`). IDs compare by their text form, so `1` and `"1"` collide. Only in [`Validation.Strict`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/validation.md>) mode; in `Validation.Repair` mode the last one wins, at the position of the first. |
| `resources[i].capacity` | `Capacity` is negative, `NaN` or infinite. |
| `resources[i].calendar_id` | In [`CalendarMode.Resource`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/calendar-mode.md>), `CalendarId` names no calendar (`"unknown calendar_id"`). |

A task calendar and a resource calendar with no common weekly working time are reported on the assignment that joins them; see [`AssignmentData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/assignment-data.md>).

## Example

```csharp
using Plen;

var monday = Moment.FromYmdHm(2026, 3, 2, 8, 0) ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Calendars =
    [
        new CalendarData
        {
            Id = "mornings",
            Worktime = new Worktime { Hours = [new TimeRange(8 * 60, 12 * 60)] },
        },
    ],
    Tasks = [new TaskData("build") { StartDate = monday, Duration = 2 }],
    Resources =
    [
        // Capacity falls back to Config.DefaultResourceCapacity (1.0).
        new ResourceData { Id = "dev" },
        // Two people who work mornings only.
        new ResourceData { Id = "qa", Capacity = 2, CalendarId = "mornings" },
    ],
    Assignments =
    [
        new AssignmentData { Task = "build", Resource = "dev", Value = 1 },
        new AssignmentData { Task = "build", Resource = "qa", Value = 1 },
    ],
};

var result = Engine.Schedule(data, new SolveOptions());
```

## Related

- [`AssignmentData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/assignment-data.md>) - books the resource on a task
- [`ResourceUpdate`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/resource-update.md>) - edits an existing resource
- [`CalendarMode`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/calendar-mode.md>) - when the resource calendar applies
- [Resources and assignments](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/resources-and-assignments.md>) - capacity and overallocation
- [Working time and calendars](<https://docs.dhtmlx.com/planning-engine/net/scheduling/working-time-calendars.md>) - resource calendars
